7

我需要从 Java 代码中调用外部 DLL 库函数。我使用 Netbeans 7.2。我的dll的功能是:

Boolean  isValid(string  word)
List<String> getWords(String  word)

我正在关注这个例子。但我不知道如何声明我的 dll 函数。我找到了另一个链接。但这对我不起作用。

4

4 回答 4

8

我偶然发现了“从 Java 调用 DLL”的相同问题,并且首先对复杂性感到沮丧。然而,有一个优雅的解决方案(对于 processing.org 栖息地的人们来说可能也很有趣..)鉴于问题的相当“一般”形式(也许,降级是不合理的),我想,将提出一个相当容易的解决方案。换句话说,一种避免与头文件、额外转换等混淆的解决方案,就像源代码不一定可用一样。

我的建议是 JNA(https://github.com/twall/jna),它基本上是 JNI 的简化包装器。它工作得很好,类型映射很简单(例如 pchar = lpcstr 缓冲区 -> 字符串),尽管我只将它用于 Windows DLL 和我自己使用 Delphi-Pascal 创建的 C 样式 DLL。唯一需要考虑的是返回值应该通过函数而不是“out”标记的引用变量导出。该问题已经指向一个提供示例的链接源(因此,围绕 JNI 的答案可能在这里放错了地方)。请注意,我提供的链接还包含用于传输数组和指针的示例。

于 2013-09-30T19:51:32.537 回答
2

您将需要使用Java 本地接口 (JNI),它是一组 C/C++ 函数,允许本地代码与 java 代码交互(即从 java 函数调用接收参数、返回结果等)。编写一个接收 JNI 调用的包装 C 库,然后调用您的外部库。

例如,以下函数调用updateHandlers本机对象(存储在 Java 端中的长度)上的方法。

class MyImpl {
  void updateHandlers(JNIEnv *env) {
    this->contentHandler = ....;
  }
}

JNIEXPORT void JNICALL Java_package_Classname_updateHandlers0
  (JNIEnv *env, jobject obj, jlong ptr) 
{
  ((MyImpl*)ptr)->updateHandlers(env);
}

package.ClassName 中对应的声明是:

private long ptr; //assigned from JNI
public void updateHandlers() {
   if (ptr==0) throw new NullPointerException(); 
   updateHandlers0(ptr);
}
private native void updateHandlers0(long ptr);

static {
    try {
          /*try preloading the library external.dll*/
      System.loadLibrary("external");
    } catch (UnsatisfiedLinkError e) {
      /*library will be resolved when loading myjni*/
    }
    System.loadLibrary("myjni"); //load myjni.dll
}
于 2013-02-21T08:38:46.777 回答
1

native private ...你用你需要的签名在 java() 中声明你的本地函数;然后运行javah(JDK 随附的工具)以生成本机标头。A List<String>(实际上是 a List,因为类型擦除)jobject在本机代码中是 a 。

相应的 C 方法将是:

JNIEXPORT jobject JNICALL package_Classname_getWords(JNIEnv *env, jobject jobj, jstring word)

我认为返回一个字符串数组会更容易jobjectArray,并从返回的值中实例化 java 中的 List 。请参阅此示例

于 2013-02-21T08:56:07.303 回答
1

我前段时间确实写过示例教程,也许它会有所帮助。

http://wendro.blogspot.com/2010/03/jni-example-eclipse-dev-cpp.html

于 2013-02-21T08:21:47.053 回答