我可以将JNA与JNI混合使用

时间:2010-04-01 13:07:28

标签: java java-native-interface jna

我有一个使用JNA从Java访问的自定义DLL。到目前为止,一切都很完美。但是现在我想从我的C代码创建Java类。我假设这不能用JNA完成,所以我做的是创建一个JNI方法,但这导致我得到UnsatisfiedLinkError。所以我的问题是:在访问相同的DLL时我可以混合使用JNA和JNI吗?如果是这样,我该怎么做呢?

2 个答案:

答案 0 :(得分:4)

当然可以混合访问DLL,因为它只会加载一次。问题是如何链接到您的应用程序:

<强> JNA:

使用JNA时,您可以调用jna库的本机函数,它通过某种反射绑定到DLL中的函数。这样做的好处是您不必担心DLL中函数的名称,它们不必满足任何约定。

<强> JNI:

简单的工作方式是从java类映射到DLL中预期的方法名称。如果您的班级com.company.SomeClass包含具有此签名的函数int doStuff(int i, long john)

JNIEXPORT jint JNICALL Java_SomeClass_doStuff(JNIEnv *env, jint i, jlong john) {
    return ...whatever...
}

如果缺少此函数,则会收到UnsatisfiedLinkException。

<强>解决方案:

因为看起来你已经编写了自己的DLL,只需添加所需的函数作为包装函数,就完成了。要获取函数签名,可以使用javah命令自动创建头文件。

我建议阅读Advanced Programming for the Java 2 Platform - Chapter 5: JNI Technology

答案 1 :(得分:0)

我想添加一件事来做到这一点。不要忘记每个JNIEXPORT的extern“C”以及JNA的功能。

举个简单的例子:

// Example DLL header file MyDLL.dll
#ifdef MYDLL_EXPORTS
#define MYDLL_API __declspec(dllexport)
#else
#define MYDLL_API __declspec(dllimport)
#endif

extern "C" {
   MYDLL_API void HelloWorld(void);    
}

extern "C" {
   JNIEXPORT void JNICALL Java_MyJavaMain_HelloWorld(void); 
}

//Example CPP file MyDLL.cpp
#include "MyDLL.h"
#include "stdio.h"

extern "C" declspec(dllexport)

void HelloWorld(void){
    printf("Hello World From Dll");
}