我试图让一些JNI代码从一个应用程序更容易移植到另一个应用程序。 最终目标是创建一个可以在任何应用程序中使用的本机代码库。
到目前为止我做了什么:
创建了一个Java类,其唯一目的是调用本机方法:
package my.example.nativelib;
public class JavaToC {
public static void loadLib() {
System.loadLibrary("myLib");
}
public static int fooNative(int[] datas) {
return foo(datas);
}
public native static int foo(int[] datas);
}
在C ++端实现了JNI_OnLoad以使用javaToC
static const char* JavaWrapper = "my/example/nativelib/JavaToC";
jint foo(JNIEnv* env, jobject javaThis, jintArray datas)
{
return 0;
}
jint JNI_OnLoad(JavaVM* pVm, void* reserved)
{
JNIEnv* env;
if (pVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return -1;
}
JNINativeMethod nm[1];
nm[0].name = "foo";
nm[0].signature = "([I)I";
nm[0].fnPtr = (void*)foo;
jclass cls = env->FindClass(JavaWrapper);
env->RegisterNatives(cls, nm, 1);
return JNI_VERSION_1_6;
}
void JNI_OnUnload(JavaVM* pVm, void* reserved)
{
JNIEnv* env;
if (pVm->GetEnv(reinterpret_cast<void**>(&env), JNI_VERSION_1_6) != JNI_OK) {
return;
}
jclass cls = env->FindClass(JavaWrapper);
env->UnregisterNatives(cls);
return;
}
所以,我可以在我的应用中的任何地方拨打JavaToC.foo()
。比强制您将特定本机调用链接到特定类的方法更方便。
但如果其他人想要使用我的本机代码,他们仍然必须使用JavaToC类创建一个特定的包。
还有另一种方法可以提高JNI本机代码的可重用性吗?
你知道一些我可以用作参考的原生文库吗?
答案 0 :(得分:0)
我提出的最佳方法是 portable 独立库,然后与JNI包装器代码链接。查看JNativeHook及其支持库libUIOHook。 JNativeHook实现了JNI layer,它是libUIOHook API的简单抽象。然后,后备库可以动态或静态链接到JNI包装程序库,或在任何独立的非Java应用程序中使用。这应该给你非常好的重用,并且不需要通过JVM调试你的本机代码。
我不确定RegisterNatives方法是否真的会为代码重用提供任何帮助......但它会使您的代码变得更加复杂。即使您更改了本机方法名称,它们仍然需要接受所有JNI参数,因此您最终会执行诸如动态加载本机共享库之类的操作,然后尝试将导出的函数映射到可以在运行中使用的内容。 Java ...开始听起来很像JNA。