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

Posted

技术标签:

【中文标题】在 Eclipse IDE 中从 Java 调用 c/c++ DLL【英文标题】:call c/c++ DLL from Java in Eclipse IDE 【发布时间】: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 错误告终。 【参考方案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和库的包含目录。

【讨论】:

以上是关于在 Eclipse IDE 中从 Java 调用 c/c++ DLL的主要内容,如果未能解决你的问题,请参考以下文章

在 IDE Netbeans 中从 java 连接到 MySQL 数据库

在 Tomcat 项目中从 Java 执行 Python 脚本

在 Eclipse 中从 XML 生成 Java 代码

在 Eclipse 中从 jslint4java 中排除文件

如何在eclipse中从另一个java项目中读取项目的属性文件

如何在 Maven 中从 pom.xml 调用 testng.xml 文件