使用接口在JNI中实现回调函数

我需要使用“接口”在Java中实现回调函数。我已经将应用程序部分写为MyJavaFunction(int size,

m_GetSizeInterface);

m_GetSizeInterface是一个包含回调函数GetSize的接口。此GetSize方法在应用程序中被覆盖。在JNI中,我需要调用具有原型的CPP函数int

MyCPPFunction(int size, int (*callback)(int* ID));

如何将此GetSize作为参数传递给JNI中的MyCPPFunction?请帮忙

public int GetSize (m_SizeClass arg0)

{

g_size = arg0.size;

return 0;

}

回答:

这里的复杂之处在于您要调用本机C ++代码,而您又要调用Java方法。这实际上有点棘手。

您需要为Java调用创建一个JNI C 函数,并创建一个与MyCPPFunction回调签名匹配的C 函数。后者将充当调用java方法的包装器。

因为包装器将需要有关JNI环境的信息,而这些信息不能由参数提供(否则我们将破坏签名),因此您将创建一些全局变量来保存它:

jobject g_getSizeIface;

jmethodID g_method;

JNIEnv *g_env;

java将调用的C ++函数如下:

JNIEXPORT void JNICALL Java_ClassName_MyCPPFunction

(JNIEnv *env, jint size, jobject getSizeInterface)

{

jclass objclass = env->GetObjectClass(getSizeInterface);

jmethodID method = env->GetMethodID(objclass, "GetSize", "(m_SizeClass)I");

if(methodID == 0){

std::cout << "could not get method id!" << std::endl;

return;

}

g_method = method;

g_getSizeIface = getSizeInterface;

g_env = env

MyCPPFunction(size, WrapperFunc);

}

因此包装函数是:

int WrapperFunc(int *id)

{

jint retval;

//marshalling an int* to a m_SizeClass boogy-woogy.

...

g_env->ExceptionClear();

retval = g_env->CallIntMethod(g_getSizeIface, g_method,

/*marshalled m_SizeClass*/);

if(g_env->ExceptionOccurred()){

//panic! Light fires! The British are coming!!!

...

g_env->ExceptionClear();

}

return rvalue;

}

以上是 使用接口在JNI中实现回调函数 的全部内容, 来源链接: utcz.com/qa/413691.html

回到顶部