jni调用java方法,该方法将自定义java接口作为参数 [英] jni call java method which take a custom java interface as parameter
问题描述
我正在研究cocos2d-x平台上的一个插件项目,我想编写一些c ++包装器接口来通过 JNI 从 jar 来调用java方法
SDK。我知道如何使用JNI来调用静态java方法,但我对java函数中的interface参数感到困惑。
我有一个处理回调的cpp函数指针:
I'm working on a plugin project on cocos2d-x platform , I'd like to write some c++ wrapper interface to invoke java method through JNI from jar
SDK . I know how to use JNI to invoke a static java method, but I'm confused by the interface parameter in the java function.
I hava a cpp function pointer to handling callbacks:
typedef void (* MyCallback)(int responseCode, string arg1, set<string> arg2);
我想编写一个cpp包装器方法,如:
and I want to write a cpp wrapper method like :
static void MyCpp::setTags(set<string> tags, MyCallback callback) //it use `JNI` to invoke java method setTags(Context context, Set<String> tags, TagCallback callback).
我想在包装器中调用的java方法是
The java method I want to invoke in the wrapper is
public static void setTags(Context context, Set<String> tags, TagCallback callback)
和 TagCallback
是API用户要实现的接口。
那么,是否有可能获得 TagCallback
最终回调到 MyCallback
函数?换句话说,我可以使用 jni
将cpp函数指针转换为java接口吗?
感谢您的耐心等待。
and the TagCallback
is an interface for API user to implement.
So, is it possible to get TagCallback
finally callback to MyCallback
function? in other words , can I use jni
to convert a cpp function pointer to java interface?
Thanks for your patience .
编辑:
这里是如何使用 setTag
如果用户只想使用java:
here is how to use setTag
if user want to use java only:
public static void setTags(context, tags, new TagCallback{
@Override
public void callback(int arg0, String arg1, Set<String> arg2) {
// TODO Auto-generated method stub
}
})
我希望我的SDK用户能够像我这样使用我的cpp包装器方法:
I'd like my SDK user to use my cpp wrapper method like this:
void setTagCallback(int responseCode, string arg1, set<string> arg2){
//users handle callback themselves.
}
void someOtherMethodInvokeTheCppWrapperMethod(){
MyCallback callback = setTagCallback;
set<string> tags;
MyCpp::setTags(tags,callback);
}
推荐答案
首先你需要构建一个可以在TagCallback兼容基类中包装本机C ++函数指针的类:
Well firstly you'll need to build a class that can wrap the native C++ function pointer in a TagCallback compatible base class:
public class NativeTagCallback : TagCallback
{
protected long cppCallbackPtr;
public NativeTagCallback( long callbackPtr )
{
cppCallbackPtr = callbackPtr;
}
public native void NativeCallback( long callbackPtr, int arg0, String arg1, Set<String> arg2 );
public void callback(int arg0, String arg1, Set<String> arg2)
{
NativeCallback( cppCallbackPtr, arg0, arg2, arg2 );
}
}
本机代码定义如下:
extern "C" jvoid Java_com_wrapper_NativeTagCallback_NativeCallback( JNIEnv* pEnv, jobject jCaller, jlong cppCallbackPtr, jint arg0, jstring arg1, jobject arg2 )
{
MyCallback cppCallback = (MyCallback)cppCallbackPtr;
const char* pCString = pEnv->GetStringUTFChars( arg1, 0);
string arg1Str( pCString );
pEnv->ReleaseStringUTFChars( arg1, pCString );
set< string > arg2Set = ConvertJavaSetToCPPSet( arg2 ); // Perform your java to CPP set conversion here.
cppCallbackPtr( (int)arg0, arg1Str, arg2Set );
}
然后你将创建相关的类并将其从C ++传递给你的函数as如下:
Then you would create the relevant class and pass it to your function from C++ as follows:
void MyCpp::setTags(set<string> tags, MyCallback callback)
{
extern __thread JNIEnv* gpEnv;
// Get the setTags function.
jclass jWrapperClass = gpEnv->FindClass( "com/wrapper/cocoswrapper" ); // Insert the correct class name here.
jmethodID jWrapperSetTag = gpEnv->GetStaticMethodID( jWrapperClass, "setTags", "(Landroid/content/Context;Ljava/util/Set;Lcom/wrapper/TagCallback)V;" );
// Get the TagCallback related function
jclass jNativeTagCallbackClass = gpEnv->FindClass( "com/wrapper/NativeTagCallback" );
jclass jNativeTagCallbackConstructor = gpEnv->GetMethodID( jNativeTagCallbackClass, "<init>", "(J)V" );
jobject jNativeTagCallbackObject = gpEnv->NewObject( jNativeTagCallbackClass, jNativeTagCallbackConstructor, (jlong)callback)
// Make function call.
gpEnv->CallStaticVoidMethod( jWrapperClass, jWrapperSetTag, jAndroidContext, tags.GetJNIObject(), jNativeTagCallbackObject );
}
这篇关于jni调用java方法,该方法将自定义java接口作为参数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!