3

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

4

2 回答 2

4

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

JNA:

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

杰尼:

Simple 的工作原理是从您的 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

我推荐阅读Java 2 平台的高级编程 - 第 5 章:JNI 技术

于 2011-01-19T21:05:04.607 回答
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");
}
于 2014-08-12T08:00:41.267 回答