使用x86_64-w64-mingw32-g ++编译JNI C ++本机代码

时间:2018-06-25 20:18:57

标签: java c++ java-native-interface g++ mingw

我想编译并运行一个简单的Hello World程序,该程序从Java声明并调用本机打印方法(用C ++定义)。

HelloCPP.java

class HelloCPP{
    private native void print();
    public static void main(String [] args){
        new HelloCPP().print();
    }
    static{
        System.loadLibrary("HelloCPP");
    } 
}

HelloCPP.cpp

#include <jni.h>
#include<iostream>
#include "HelloCPP.h" 
using namespace std;

extern "C" 
JNIEXPORT void JNICALL Java_HelloCPP_print(JNIEnv *env, jobject obj){
    cout << "Hello World from C++!" << endl;
    return; 
}

在命令提示符下,运行以下命令:

  • javac HelloCPP.java
  • javah -jni HelloCPP
  • 86_64-w64-mingw32-g ++ -c -I“ C:\ Java \ jdk1.8.0_171 \ include” -I“ C:\ Java \ jdk1.8.0_171 \ include \ win32” HelloCPP.cpp
  • x86_64-w64-mingw32-g ++ -shared -o HelloCPP.dll HelloCPP.o
  • java -Djava.library.path =。 HelloCPP

然后臭名昭著的DLL链接/加载错误

  

线程“主”中的异常java.lang.UnsatisfiedLinkError:<“ MyProjectDirectory”> \ HelloCPP.dll:在java.lang的java.lang.ClassLoader $ NativeLibrary.load(本机方法)处找不到依赖库。 java.lang.System.loadLibrary(System上的java.lang.Runtime.loadLibrary0(Runtime.java:870)上的java.lang.ClassLoader.loadLibrary(ClassLoader.java:1857)上的ClassLoader.loadLibrary0(ClassLoader.java:1941) .java:1122)。(HelloCPP.java:8)

尝试的解决方案

  • java -Djava.library.path =。 HelloCPP应该检查当前项目目录,即dll的构建目录,并且应该可以链接
  • 试图将dll复制到另一个文件夹,并将该文件夹目录添加到路径系统环境变量中
  • 使用Dependency Walker,发现HelloCPP.dll正在寻找libstdc ++-6.dll和其他dll
  • 试图将这些驱动程序复制到同一目录中,然后导致连锁反应寻找其他dll
  • 尝试添加-static-libstdc ++之类的命令

附加说明

  • 我可以使用C中的本机方法运行确切的程序,并使用x86_64-w64-mingw32-gcc运行该DLL,找到该DLL,将其链接,加载并且程序可以正常运行
  • x86_64-w64-mingw32-g ++是通过Cygwin下载的
  • 切换到x86_64-w64-mingw32-g ++,是因为使用g ++时我遇到了与Cygwin compilation error Problematic frame: # C [cygwin1.dll+0xd6d47] using JNI相同的问题
  • 当前使用Sublime文本编辑器编写Java和C ++文件,然后通过命令提示符进行编译
  • 如果有人可以推荐我一个很好的IDE来与JNI一起使用,那就太好了
  • 希望第一次发帖不会错过任何重要的事情,花了很多时间来回答已经提出的问题

1 个答案:

答案 0 :(得分:1)

Java代码: helloworld.java

class helloworld{
    public native void hello();

    static {
            System.loadLibrary("hello");
    }
    public static void main(String args[]){
            new Helloworld().hello();
    }
}

cpp代码: 你好。c

#include<iostream>
#include "helloworld.h"
using namespace std;
JNIEXPORT void JNICALL Java_helloworld_hello(JNIEnv *env, jobject obj)
{
    cout<<"Hello World";

    return;
}

命令

javac -h . helloworld.java
g++ -I /usr/lib/jvm/java-8-oracle/include/ -I /usr/lib/jvm/java-8-oracle/include/linux/ hello.cpp -shared -o libhello.so -fPIC
java -Djava.library.path=. helloworld