我想使用C ++模板生成槽函数,并将这些函数注册到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?
答案 0 :(得分:1)
在模板中添加一个整数作为参数来制作独特的模板,并使用宏 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(...)也可以生成不同的静态方法。如果相同的签名函数绑定了相同的行号,您可以将它们与jclass区分开来(参见注释2)。