java - 使用c++模板生成JNI函数

标签 java c++ templates binding java-native-interface

我想使用C++模板生成slot函数,并将这些函数注册到java代码可以调用的jvm中,比如:

template<typename Arg1>
void bind_native(const char* className, const char* staticMethodName, function<void(Arg1)>* slotFunc)
{
    JNINativeMethod sig;
    sig.name        = staticMethodName;
    sig.signature   = Wrapper<void(Arg1)>::Get().GetSignature();
    sig.fnPtr       = Wrapper<void(Arg1)>::Get().GetSlotFunc(slotFunc);

    // register to jni..
}

// bind our native function to java.
function<void(int)> cppIntFunc = [](int intFromJava) 
{ 
    printf("called from java");
};
bind_native("MyClass", "MyCppMethod", &cppIntFunc);

// we can also bind different functions with the same signature to jni.
function<void(int)> cppIntFunc1;
function<void(int)> cppIntFunc2;
bind_native("MyClass", "MyCppMethod1", &cppIntFunc1);
bind_native("MyClass", "MyCppMethod2", &cppIntFunc2);

// in java code:
class MyClas {
    private static native MyCppMethod(int i);
    private static native MyCppMethod1(int i);
    private static native MyCppMethod2(int i);
}

但问题是,同一个模板生成同一个函数,所以我无法区分在jni中调用了哪个方法,因此我无法取回原始槽函数:

template<typename Arg1>
struct Wrapper
{
    void* GetSlotFunc(function<void(Arg1)>* slotFunc)
    {
        // how to map the slotFunc to the StaticJniFunc?

        return StaticJniFunc;
    }

    static JNICALL void StaticJniFunc(JNIEnv* e, jclass c, Arg1 param1)
    {
        // how to get the slotFunc back here? 

        (*slotFunc)(param1);
    }
};    

也许我需要找到一种方法从 jni 获取正在运行的 jmethodID?

最佳答案

将一个整数作为参数添加到模板中以制作独特的模板,并使用宏LINE 自动生成该整数(见注释1):

// note 1
template<int METHODID, typename Arg1>
struct Wrapper
{
    map<string, SlotFuncPtr> funMap;

    void* GetSlotFunc(const char* className, function<void(Arg1)>* slotFunc)
    {
        funcMap[className] = slotFunc; // note 2
        return StaticJniFunc;
    }

    static JNICALL void StaticJniFunc(JNIEnv* e, jclass c, Arg1 param1)
    {
        auto* slotFunc = funcMap[getClassName(c)]; // note2

        (*slotFunc)(param1);
    }
};

// note1
#define bind_native(name,f) bind_native_<__LINE__>(name,f)

然后 bind_native(...) 可以生成不同的静态方法,即使对于具有相同签名的方法也是如此。如果相同的签名函数与相同的行号绑定(bind),您可以将它们与 jclass 区分开来(见注 2)。

关于java - 使用c++模板生成JNI函数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26776574/

相关文章:

java - Sonar 违反 if 语句中未使用的方法

java - 在@Scheduled中分配字符串(cron ="Some String")

c++ - 在 C++ 中的字符串中搜索字符串

wpf - DataGridCell.Template 样式覆盖 IsSelected 触发器

c++ - 在 Eigen 中使用 CwiseBinaryOp 时如何摆脱 "invalid use of incomplete type"

java - 改变纹理的高度使纹理出现在地面之上

java - 使用java录制网络广播流

c# - 使用相同的方法名称调用多个 dll 导入

c# - 向 C# 公开 ISO C++ 类

c++ - template模板类的param怎么取