Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用接口在JNI中实现回调函数_Java_Interface_Callback_Java Native Interface_Function Pointers - Fatal编程技术网

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

Java 使用接口在JNI中实现回调函数,java,interface,callback,java-native-interface,function-pointers,Java,Interface,Callback,Java Native Interface,Function Pointers,我需要使用“接口”在Java中实现回调函数。我将应用程序部分编写为MyJavaFunction(int size,m_GetSizeInterface) m_GetSizeInterface是一个包含回调函数GetSize的接口。此GetSize方法在应用程序中被重写。在JNI中,我需要调用一个具有原型intmycppfunction(int-size,int(*callback)(int*ID))的CPP函数 如何将此GetSize作为参数传递给JNI中的MyCPPFunction?请帮忙 p

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

m_GetSizeInterface是一个包含回调函数GetSize的接口。此GetSize方法在应用程序中被重写。在JNI中,我需要调用一个具有原型
intmycppfunction(int-size,int(*callback)(int*ID))的CPP函数

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

public int GetSize (m_SizeClass arg0)
{
    g_size = arg0.size;
        return 0;
}

<>这里的复杂之处在于,您希望调用本地的C++代码,而代码反过来又希望调用java方法。这实际上有点棘手

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

因为包装器将需要关于JNI环境的信息,而这些信息不能由参数提供(以免破坏签名),所以您可以创建几个全局变量来保存它:

jobject g_getSizeIface;
jmethodID g_method;
JNIEnv *g_env;

java调用C++函数的方法如下:< /P>

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);
}
#包括
#包括
#包括
类SimpleQueueEvent{
公众:
SimpleQueueEvent(){};
~simplequeeevent(){};
//用于C++代码调用
int queueEvent(std::function func){
int curTime=time(0)+rand()%10000;
insert(std::map::value_type(curTime,func));
返回短时间;
//调用Java方法来调用方法,例如
//环境->FindClass(“…”);
//jmethodID method=env->FindMethod(“onPostQueueEvent”…);
//env->InvokeVoidMethod();
//像这样的Java代码。。
//私有void onPostQueueEvent(最终int eventId){
//PostQueueEvent(新的Runnable(){
//公开募捐{
//nativeEventFunc(事件ID);
//    }
// });
//私有静态本机void nativeEventFunc(int-eventId);
}
void nativeEventFunc(int eventId){
if(eventMaps.find(eventId)!=eventMaps.end(){
std::function func=eventMaps.at(eventId);
func();
}
}
私人:
地图事件地图;
};
//测试代码为:

 SimpleQueueEvent queueEvent;
    std::function<void(void)> func = [](){
        printf("native runnable..\n");
    };

    int evenId = queueEvent.queueEvent(func);
    queueEvent.nativeEventFunc(evenId);
SimpleQueueEvent队列事件;
std::函数func=[](){
printf(“本机可运行..\n”);
};
int evenId=queueEvent.queueEvent(func);
queueEvent.nativeEventFunc(evenId);

我们可以拥有完整的函数示例代码吗..Java层的声明是什么?如果需要多次使用本机代码注册回调(传递不同的接口实现),那么每个WrapperFunc注册都有一个关联的接口对象/方法来调用呢
#include <functional>
#include <cstdlib>
#include <map>

class SimpleQueueEvent {

public:

    SimpleQueueEvent(){};
    ~SimpleQueueEvent(){};

    //for C++ code call
    int queueEvent(std::function<void(void)> func){
        int curTime = time(0) + rand() % 10000;
        eventMaps.insert(std::map<int, std::function<void(void)>>::value_type(curTime, func));
        return curTime;

        //Call Java method to invoke method, such as
        //env->FindClass("....");
        //jmethodID method = env->FindMethod("onPostQueueEvent"...);
        //env->InvokeVoidMethod();

        //Java code like this..
        // private void onPostQueueEvent(final int eventId){
        // listener.PostQueueEvent(new Runnable() {
        //    public void run() {
        //        nativeEventFunc(eventId);
        //    }
        // });
        // private static native void nativeEventFunc(int eventId);

    }

    void nativeEventFunc(int eventId){
        if(eventMaps.find(eventId) != eventMaps.end()){
            std::function<void(void)> func = eventMaps.at(eventId);
            func();
        }
    }



private:
    std::map<int, std::function<void(void)>> eventMaps;


};
 SimpleQueueEvent queueEvent;
    std::function<void(void)> func = [](){
        printf("native runnable..\n");
    };

    int evenId = queueEvent.queueEvent(func);
    queueEvent.nativeEventFunc(evenId);