2

I am using android NDK with C++, the problem I am facing is that I don't know how to create object of the c++ class in order to access its methods inside activity.

Any idea how to do it ? Thanks.

3 Answers 3

4

First of all, Activity is a controller from MVC viewpoint, an activity gets destroyed when the screen orientation changes from, say, vertical to horizontal. First create a class able to outlive the activities and use the native resources from there.

I assume you know how to create and invoke native functions, and know how to create a C++ object. I also assume you know what

#ifdef __cplusplus
extern "C" {
#endif

and

#ifdef __cplusplus
}
#endif

do in a .h file (they allow functions compiled with C++ (not member functions, just functions) be visible from C).

Now, calling C++ object instance methods from Java is basically the same as calling C++ object instance methods from plain C. Instead of doing

myObject.myMethod(arg1,arg2, ...)

you will have to do

callMyMethod(myObjHandle, arg1, arg2, ...)

where myObjHandle may be the native address of the C++ object converted into an int.

You, of course, will have to care about deleting that C++ object -- Java has no means to know that some integer value must be passed to C++ to either delete or delete[] it.

And a good news for you is that the same threads are used for Java and native code.

Sign up to request clarification or add additional context in comments.

4 Comments

What do you mean by myObject? Where did you instantiate it?
@IgorGanapolsky It was a good while ago, but in this context myObject may only mean a C++ object, and this object must be created via new in a C++ function, and then its address may be interpreted as an integer and passed to Java, and for Java it will be just an integer handle rather than an object.
myObject.myMethod does not seem like an integer handle to me. It is not an integer operation.
@IgorGanapolsky Of course the C++ object instance address is not a number. There's no void* in Java, therefore it is a long (just in case that addresses are 64-bit). And for every C++ instance method you have to define an auxiliary JNI function (which is really boring and cumbersome).
1

To call the C++ method from Activity you need to declare that method as 'native'.

//MultiPlayerJNI.java
public static native void onNetworkDataReceived(int index);

//MultiPlayerJNI.h
void Java_com_example_game_MultiPlayerJNI_onNetworkDataReceived(JNIEnv *env, jobject thiz, jint spIndex);

//MultiPlayerJNI.cpp
void Java_com_example_game_MultiPlayerJNI_onNetworkDataReceived(JNIEnv *env, jobject thiz, jint spIndex){
DebugLog("JNI onNetworkDataReceived");

if(MultiplayerJNI::getInstance()->multiGameController != NULL){
    MultiPlayerJNI::getInstance()->multiGameController->onNetworkDataReceived(spIndex);
}else if(MultiPlayerJNI::getInstance()->singleGameController != NULL){
    MultiPlayerJNI::getInstance()->singleGameController->onNetworkDataReceived(spIndex);


   }
}

To call Java method from C++

//MultiPlayerJNI.h
void getTableInfo();

//MultiPlayerJNI.cpp
void MultiPlayerJNI::getTableInfo(){
DebugLog("MultiPlayerJNI::getTableInfo()");
 JniMethodInfo t;
    if (JniHelper::getStaticMethodInfo(t
                                , "com/example/game/MultiPlayerJNI"
                                , "getTableInfo"
                                , "()V"))
        {
         t.env->CallStaticVoidMethod(t.classID,t.methodID);
            t.env->DeleteLocalRef(t.classID);
            }
}
//MultiPlayerJNI.java
public static void getTableInfo(){

}

I would suggest creating Singleton JNI classes for Java and CPP part.

1 Comment

I think OP's question was not about calling individual functions, but rather to instantiate a whole class.
0

I sometimes use C or C++ in my Android Project. But create Java object in C/C++ source code. If you will create C++ class in your Java source code, maybe ...

( I understood what do you want and only I give an idea. Maybe create Java Object in C++ source code)

this is my example;(In example deployed Java object in native code.)

// JAVA CODE

public class mActivity extends Activity{

public native Object get();
public native void set(Object data);
}

// C CODE

typedef struct data_type
{
    jobject data;
    struct data_type* next;
}DATA_TYPE;

jobject Java_com_example_nativequeue_TestActivity_get(JNIEnv* env, jobject thiz)
{
    if(HEADER != NULL){
        jobject result = HEADER->data;
        --data_struct_size;
        return result;
    }

    if(HEADER->next != NULL)
        HEADER = HEADER->next;


    return NULL;
}

void Java_com_example_nativequeue_TestActivity_set(JNIEnv* env, jobject thiz, jobject data)
{
    jobject new_data = (*env)->NewGlobalRef(env, data);
    if(new_data == NULL){
        return;
    }

    NEW = (DATA_TYPE*)malloc(sizeof(DATA_TYPE));
    NEW->data = new_data;
    NEW->next = NULL;

    if(HEADER == NULL){
        HEADER = NEW;
        FOOTER = HEADER;
    }else{
        FOOTER->next = NEW;
        FOOTER = NEW;
    }

    ++data_struct_size;

}

2 Comments

Where do you declare HEADER?
HEADER is global variablr. I'm not show decleration because simple linked list example

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.