2016-04-25 44 views
1

我想寫一組JNI調用在我的java項目中使用一些C++代碼。當我將它寫成C代碼並使用GCC編譯時,它似乎很好,函數名稱正確(Java_myPackage_MyClass_myFunction)。G ++編譯的DLL有不同的函數名

但是我發現用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) 

當我檢查在Dependency Walker中的dll,該功能的名稱有誤吧,它被改爲_Z52Java_package_class_functionP7JNIENV_P8_jobjectP8_jstringS4_

當我認爲它應該只顯示在依賴walker中Java_package_class_function

這是我使用的編譯使用g ++

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 

該DLL的命令是有什麼我缺少彙編?我在我的.h文件中列出的函數名爲JNExport,並以extern「C」{}包裝。我只是不完全清楚爲什麼函數命名/調用在編譯時會發生變化。

環境是在Win7上的Cygwin中編譯的G ++,用於Java的JDK 1.8。在我的.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在那裏,和AES功能正在.dll文件正確導出,但其他兩個功能所得到的多餘裝飾。

回答

0

C++編譯器使用名稱修改在符號表中創建唯一條目。這在C代碼中是不需要的,因爲每個函數都必須是唯一的。爲了防止名稱損壞包裝您的函數定義在extern "C" { }

欲瞭解更多信息,請參閱in-c-source-what-is-the-effect-of-extern-ca duplicate of your question

+0

我確實在.h文件中包含extern c中的聲明。我將添加我的.h文件的要點到上面的問題 – jspriggs