【问题标题】:How to call external dll function from java code如何从java代码调用外部dll函数
【发布时间】:2013-02-06 11:40:57
【问题描述】:

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

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

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

【问题讨论】:

  • “它对我不起作用”对于我们来说几乎不足以帮助您。您需要告诉我们您尝试了什么,结果如何。请阅读tinyurl.com/so-list
  • 什么不起作用?你能分享一些你尝试过的代码吗?

标签: java dll call jna


【解决方案1】:

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

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

【讨论】:

    【解决方案2】:

    您使用所需的签名在 java (native private ...) 中声明您的本机函数;然后运行javah(JDK 提供的一个工具)以生成本机头文件。 List&lt;String&gt;(实际上是 List,因为类型擦除)在本机代码中是 jobject

    对应的 C 方法是:

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

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

    【讨论】:

      【解决方案3】:

      您将需要使用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
      }
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

        • 这是一个仅链接的答案,一般情况下是不可接受的。
        猜你喜欢
        • 2014-05-16
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-07-29
        • 1970-01-01
        • 2019-12-13
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多