我正在尝试编写一组JNI调用,以便在我的java项目中使用一些C ++代码。当我把它写成C代码并用GCC编译时,它看起来很好并且函数名称是正确的(Java_myPackage_MyClass_myFunction)。
但我发现用C ++而不是C来做我想要的更容易。当我尝试编译我用C ++编写的代码时,我能看到的所有头文件都是正确的,一切看起来都很好,但是当我编译它,g ++生成的DLL在我的java代码中导致了这个错误:
Exception in thread "main" java.lang.UnsatisfiedLinkError: package.class.function(Ljava/lang/String;Ljava/lang/String;)Ljava/lang/String;
at package.class.function(Native Method)
当我在依赖walker中检查dll时,该函数的名称错误,它已被更改为_Z52Java_package_class_functionP7JNIENV_P8_jobjectP8_jstringS4 _
当我认为它应该只是在依赖walker中显示为Java_package_class_function
这是我用来用g ++编译dll的命令
g++.exe -Wl,--add-stdcall-alias -I "C:\Program Files\Java\jdk1.8.0_73\include" -I "C:\Program Files\Java\jdk1.8.0_73\include\win32" -shared -o C:/repos/myproject.dll myproject.cpp -lssl -lcrypto
编辑中是否有我遗漏的东西?我的.h文件中的函数列为JNExport并包含在extern“C”{}中。我还不完全清楚为什么函数命名/调用在编译时会发生变化。
环境是在Win7上用Cygwin编译的G ++,JDK 1.8 for Java。
我的.h文件中的函数声明:
extern "C" {
JNIEXPORT jstring JNICALL Java_package_class_function(JNIEnv *, jclass, jstring, jstring);
JNIEXPORT jstring JNICALL Java_package_class_function(JNIEnv *, jclass, jstring, jstring);
char * aes_encrypt_string(char *, char *, char *);
char * aes_decrypt_string(char *, char *, char *);
}
我有externc,并且在.dll文件中正确导出了aes函数,但其他2个函数正在获得额外的装饰。
答案 0 :(得分:0)
C ++编译器使用名称修改来在符号表中创建唯一条目。在C代码中不需要这样做,因为每个函数必须已经是唯一的。为防止名称修改在extern "C" { }
有关详细信息,请参阅in-c-source-what-is-the-effect-of-extern-c和a duplicate of your question。