如何从java代码调用外部dll函数

时间:2013-02-21 08:07:44

标签: java dll call jna

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

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

我正在关注this示例。但我不知道如何声明我的dll功能。 我找到了另一个link。但它对我不起作用。

4 个答案:

答案 0 :(得分:6)

我偶然发现了“从Java调用DLL”的问题,并且首先对复杂性感到沮丧。然而,有一个优雅的解决方案(也可能对那里的人们在processing.org栖息地感兴趣..) 考虑到问题的相当“一般”形式(可能,对此不合理,我认为,这是一个相当容易解决的问题)。换句话说,这个解决方案可以避免使用头文件,额外的转换等来破坏aronud,就像源代码不一定可用一样。

我对此的建议是JNA(https://github.com/twall/jna),它基本上是JNI的简化包装器。它工作得很好,类型映射很简单(例如pchar = lpcstr buffer - &gt; string),虽然我只使用它来使用Windows DLL和我自己使用Delphi-Pascal创建的C风格的DLL。唯一要考虑的是返回值应该通过函数而不是“out”标记的引用变量导出。 问题已经指向一个链接源,为此提供了一个示例(因此,JNI的答案可能在这里放错了位置)。请注意,我提供的链接还包含用于传输数组和指针的轴样本。

答案 1 :(得分:2)

您需要使用Java Native Interface (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
}

答案 2 :(得分:1)

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

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

答案 3 :(得分:1)

使用您需要的签名在java(native private ...)中声明您的本机函数;然后运行javah(随JDK提供的工具)以生成本机头。由于类型擦除,List<String>(实际上是List)是本机代码中的jobject

相应的C方法是:

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

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