【问题标题】:call c/c++ DLL from Java in Eclipse IDE在 Eclipse IDE 中从 Java 调用 c/c++ DLL
【发布时间】:2021-08-28 06:09:45
【问题描述】:

我想调用这个最小的虚拟 C 程序(名为“TEST.c”):

extern "C"
void Java_TEST_run() {}

来自此 Java 代码(名为“Example.java”):

public class Example 
{
    public static void main(String args[]) 
    {
      System.out.println("START");   

      TEST test = new TEST(); 

      test.dll_call();

      System.out.println("ALL DONE!");      
    }   
}    

class TEST
{
    public void dll_call()
    {
      run();       
    }
    static {
        try {
            System.out.println("Load DLL = start ");

            System.load("/home/user/Desktop/TEST.dll");

            System.out.println("Load DLL = finish ");
        } catch (UnsatisfiedLinkError e) {
          System.err.println("Native code library failed to load.\n");
          System.exit(1);
        }
      }
     public native void run();    
}

我通过以下命令创建 C dll 文件:

g++ -c  TEST.c
g++ -shared  -o TEST.dll TEST.o

这在控制台环境中运行良好,尤其是。我得到了成功的Java程序执行输出:

START
Load DLL = start 
Load DLL = finish 
ALL DONE!

现在,如果我尝试从 Eclipse IDE 运行 Java 程序,则会收到以下错误:

START
Load DLL = start 
Load DLL = finish 
Exception in thread "main" java.lang.UnsatisfiedLinkError: 'void Example.TEST.run()'
    at test1/Example.TEST.run(Native Method)
    at test1/Example.TEST.dll_call(Example.java:21)
    at test1/Example.Example.main(Example.java:11)

据我了解,这意味着从 Eclipse 运行的 Java 程序确实成功地找到了 c dll 文件,但是在尝试输入 dll 文件时,由于找到了虚拟函数 Java_TEST_run() 而失败。

由于 c 代码“TEST.c”已经尽可能少,并且从控制台执行正常,我不明白为什么它在 Eclipse 中失败。

谁能给我建议,如何在 Eclipse 中让这个最小的 c 代码在 Java 中工作?


操作系统是 Ubuntu 18.04,openjdk 11.0.6 和 Eclipse 4.14.0。

这是来自question 的后续问题。

非常感谢您的帮助,谢谢!

【问题讨论】:

  • 像这样的native 方法必须按照jni 规范进行编译,并且比这更复杂,或者使用jna 库为您完成大部分工作。
  • 感谢您的评论,格雷格!我最初尝试使用 JNI 语句(包括 C 代码和编译命令中的标头),它在控制台中运行良好,但是当我尝试从 Eclipse 运行 Java 代码时,我遇到了同样的 UnsatisfiedLink 错误。因此,我试图获得一个在 Eclipse 中工作的最小示例。但到目前为止,我未能从 Eclipse 获得任何 DLL 调用。我还尝试了 Eclipse 网络上的各种“hello world”dll 示例,但总是以 unsatisfiedLink 错误告终。

标签: java c++ c eclipse dll


【解决方案1】:

我能够用 Eclipse 解决问题。

C/C++ 代码需要包含 Eclipse 项目的名称,例如“示例”,在函数名称中。在上面的代码中,这意味着:

外部“C” 无效 Java_TEST_run() {}

需要改成:

外部“C” 无效 Java_Example_TEST_run() {}

【讨论】:

    【解决方案2】:

    我会尽快给你答复 首先,您将需要用于 c/c++ 的 JNI,它将为您的 .java 文件生成标头。 例如,如果我们有你的例子中的类,我们将有这样的标题输出

    /* DO NOT EDIT THIS FILE - it is machine generated */
    #include <jni.h>
    /* Header for class TEST */
    
    #ifndef _Included_TEST
    #define _Included_TEST
    #ifdef __cplusplus
    extern "C" {
    #endif
    /*
     * Class:     TEST
     * Method:    run
     * Signature: ()V
     */
    JNIEXPORT void JNICALL Java_TEST_run
      (JNIEnv *, jobject);
    
    #ifdef __cplusplus
    }
    #endif
    #endif
    

    您可以通过键入来生成这种类型的标题 javac -h . TEST.java 给你的班级

    我们要做的最后一件事是创建我们的 .cpp 文件来添加函数体,你可以从 JNI 生成的头文件中复制 decleration

    #include "TEST.h"
    JNIEXPORT void JNICALL Java_TEST_run(JNIEnv * env, jobject obj){
        //my very special code
    }
    

    就是这样。 为了将 JNI 添加到您的 Visual Studio(如果您正在使用),您必须转到项目属性并从 jdk 文件夹添加其他包含和其他库。 如果您使用的是g++,请添加JDK和库的包含目录。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-01-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多