在 Eclipse IDE 中从 Java 调用 c/c++ DLL

call c/c++ DLL from Java in Eclipse IDE

我想调用这个最小的虚拟 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 程序 运行ning 确实成功地找到了 c dll 文件,但是当试图进入 dll 文件时,它因找到虚拟函数而失败Java_TEST_run().

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

有人能给我建议吗,如何使这个最小的 c 代码在 Eclipse 中从 Java 运行?


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

这是 的后续问题。

非常感谢任何帮助,谢谢!

我会尽快给你答复 首先,c/c++ 需要 JNI,它会为你的 .java 文件生成 header。 例如,如果我们从您的示例中得到 class,我们将得到 header 这样的输出

/* 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

您可以通过键入来生成这种 header javac -h . TEST.java 给定 class

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

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

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

我能够使用 Eclipse 解决问题。

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

外部“C” void Java_TEST_run() {}

需要改为:

外部“C” void Java_Example_TEST_run() {}