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.
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.
myObject? Where did you instantiate it?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.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.
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;
}