java調用dll或so動態庫文件(c++/c)開發平台:Eclipse3.3.1.1+CDT(cdt-master-4.0.3)+MinGW(MinGW-5.1.4)
一:下面是java調用dll(C++)
1:下載並安裝cdt :http://www.eclipse.org/cdt/downloads.php :選擇自己eclipse 支持的cdt插件,下載,並且
通過eclipse-->software update-->find and install 安裝cdt
2:下載並安裝mingw :http://sourceforge.net/project/showfiles.php?group_id=2435
然后,點擊mingw.exe,選擇 下載並安裝 ,然后都選中(速度可能有點慢,要有耐心),
3:環境變量配置(在系統變量或者用戶變量里添加以下變量,注意路徑根據實際安裝的進行修改):
PATH: D:\Program Files\MinGW\bin
C_INCLUDE_PATH: D:\Program Files\MinGW\include
CPLUS_INCLUDE_PATH: D:\Program Files\MinGW\include\c++\3.4.5;D:\Program Files\MinGW\include\c++\3.4.5\mingw32;D:\Program Files\MinGW\include\c++\3.4.5\backward;D:\Program Files\MinGW\include
LIBRARY_PATH: D:\Program Files\MinGW\lib
LIBRARY_PATH 這個 變量最好加上,以前沒有加,也可以編譯出正確的dll,但是后來編譯出來的dll就有問題,最后定位出來沒有加LIBRARY_PATH這個變量,造成編譯出來的dll不能正常運行.
如果添加完所有變量 最好重啟電腦。
4:相關設置
eclipse-->Window->Preferences->C/C++->New CDT project wizard->Makefile Project
找到 Binary Parser 把Elf Parser取消, 選中 PE Windows Parser.
由於在MinGW目錄下的make文件名為"mingw32-make.exe", eclipse默認的調用文件名為"make.exe"
所以先將MinGW目錄下文件名為"mingw32-make.exe"做個備份,然后將該文件重命名為"make.exe"
5:java工程和 c++工程,還是以經典的HelloWorld為例
然后編譯生成class文件,用命令javah class文件生成頭文件Hello.h
創建c++工程:
注意:
1>:在eclipse設置c++ build 模式:將 release 狀態改為active,否則java程序調用生成的dll會報以下錯誤
Exception in thread "main" java.lang.UnsatisfiedLinkError:
2>:編譯的時候如果報以下錯誤,解決方法就是在.h文件和.cpp文件里添加一個int mian()方法
**** Rebuild of configuration Debug for project HelloC++ ****
**** Internal Builder is used for build ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -oHello.o ..\Hello.cpp
..\Hello.cpp:10:2: warning: no newline at end of file
g++ -LD:\Program Files\Java\jdk1.6.0_10\include\win32 -LD:\Program Files\Java\jdk1.6.0_10\include -oHelloC++.exe Hello.o
D:/Program Files/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../libmingw32.a(main.o):main.c:(.text+0xbd): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
Build error occurred, build is stopped
Time consumed: 5192 ms.
------------------------------------------------------------------------------
修改后的Hello.h內容:
修改后的Hello.cpp內容:
a:然后用eclipse c++插件的 make targets--build生成Hello.o
target name 隨便
make target 隨便
命令默認就可以
b:將wingw/bin下的g++考到 剛才生成的Hello.o同級目錄下,然后在命令行里切換到Hello.o所在的目錄
執行命令,注意參數(我的java目錄D:\Program Files\Java\):
g++ -I"D:\Program Files\Java\jdk1.6.0_10\include" -Wl,--add-stdcall-alias -shared -o Hello.dll Hello.o
6:運行:
將剛才生成的dll文件拷貝到java工程的根目錄下,運行Hello.class即可
注意:如果測試類是在某個包下的話,例如:com.test.Hello,那我們編譯class文件的時候: javac com\test\Hello.java
然后: javah com.test.Hello,這樣生成的頭文件中的方法在被調用的時候才能找到。
二:java調用so(C)
java和c / c++通信都可以通過jni來實現。 在java代碼中:
System.loadLibrary("Hello");
Hello不能寫成Hello.dll或者Hello.so,它會根據系統平台自動填充,需要注意的是在unix/linux下生成.so動態庫文件的時候,
需要在Hello.so前添加lib,否則找不到.so文件(libHello.so),運行的時候需要指定.so的路徑:
java -Djava.library.path=/homw/user/so所在目錄 -jar Hello.jar
三:命令整理:
以c為例(如果是c++,則把gcc改成g++就OK):
1:在unix/linux環境下
1.1:生成.o文件
gcc -I/usr/lib/j2sdk1.5-ibm/include -fPIC -c example.c
1.2:生成動態庫.so文件
gcc -shared -WI -soname example.o -o libexample.so
2:在windows環境下
2.1:生成.o文件
gcc -c -I"D:\Program Files\Java\jdk1.6.0_10\include" -I"D:\Program Files\Java\jdk1.6.0_10\include\win32" -o Hello.o Hello.c
2.2:生成dll文件
gcc -I"D:\Program Files\Java\jdk1.6.0_10\include" -Wl,--add-stdcall-alias -shared -o Hello.dll Hello.o
由於時間關系,寫得比較亂,o(∩_∩)o...
一:下面是java調用dll(C++)
1:下載並安裝cdt :http://www.eclipse.org/cdt/downloads.php :選擇自己eclipse 支持的cdt插件,下載,並且
通過eclipse-->software update-->find and install 安裝cdt
2:下載並安裝mingw :http://sourceforge.net/project/showfiles.php?group_id=2435
然后,點擊mingw.exe,選擇 下載並安裝 ,然后都選中(速度可能有點慢,要有耐心),
3:環境變量配置(在系統變量或者用戶變量里添加以下變量,注意路徑根據實際安裝的進行修改):
PATH: D:\Program Files\MinGW\bin
C_INCLUDE_PATH: D:\Program Files\MinGW\include
CPLUS_INCLUDE_PATH: D:\Program Files\MinGW\include\c++\3.4.5;D:\Program Files\MinGW\include\c++\3.4.5\mingw32;D:\Program Files\MinGW\include\c++\3.4.5\backward;D:\Program Files\MinGW\include
LIBRARY_PATH: D:\Program Files\MinGW\lib
LIBRARY_PATH 這個 變量最好加上,以前沒有加,也可以編譯出正確的dll,但是后來編譯出來的dll就有問題,最后定位出來沒有加LIBRARY_PATH這個變量,造成編譯出來的dll不能正常運行.
如果添加完所有變量 最好重啟電腦。
4:相關設置
eclipse-->Window->Preferences->C/C++->New CDT project wizard->Makefile Project
找到 Binary Parser 把Elf Parser取消, 選中 PE Windows Parser.
由於在MinGW目錄下的make文件名為"mingw32-make.exe", eclipse默認的調用文件名為"make.exe"
所以先將MinGW目錄下文件名為"mingw32-make.exe"做個備份,然后將該文件重命名為"make.exe"
5:java工程和 c++工程,還是以經典的HelloWorld為例
- public class Hello {
- public native void sayHello();
- static{
- System.loadLibrary("Hello");
- }
- public static void main(String[] args){
- Hello h = new Hello();
- h.sayHello();
- }
然后編譯生成class文件,用命令javah class文件生成頭文件Hello.h
創建c++工程:
注意:
1>:在eclipse設置c++ build 模式:將 release 狀態改為active,否則java程序調用生成的dll會報以下錯誤
Exception in thread "main" java.lang.UnsatisfiedLinkError:
2>:編譯的時候如果報以下錯誤,解決方法就是在.h文件和.cpp文件里添加一個int mian()方法
**** Rebuild of configuration Debug for project HelloC++ ****
**** Internal Builder is used for build ****
g++ -O0 -g3 -Wall -c -fmessage-length=0 -oHello.o ..\Hello.cpp
..\Hello.cpp:10:2: warning: no newline at end of file
g++ -LD:\Program Files\Java\jdk1.6.0_10\include\win32 -LD:\Program Files\Java\jdk1.6.0_10\include -oHelloC++.exe Hello.o
D:/Program Files/mingw/bin/../lib/gcc/mingw32/3.4.5/../../../libmingw32.a(main.o):main.c:(.text+0xbd): undefined reference to `WinMain@16'
collect2: ld returned 1 exit status
Build error occurred, build is stopped
Time consumed: 5192 ms.
------------------------------------------------------------------------------
修改后的Hello.h內容:
- /* DO NOT EDIT THIS FILE - it is machine generated */
- #include <jni.h>
- /* Header for class Hello */
- #ifndef _Included_Hello
- #define _Included_Hello
- #ifdef __cplusplus
- extern "C" {
- #endif
- /*
- * Class: Hello
- * Method: sayHello
- * Signature: ()V
- */
- int main() ;
- JNIEXPORT void JNICALL Java_Hello_sayHello
- (JNIEnv *, jobject);
- #ifdef __cplusplus
- }
- #endif
- #endif
修改后的Hello.cpp內容:
- #include <iostream>
- #include "Hello.h"
- using namespace std;
- int main()
- {
- return 1;
- }
- JNIEXPORT void JNICALL Java_Hello_sayHello(JNIEnv *, jobject){
- printf("Hello world!\n");
- return ;
- }
a:然后用eclipse c++插件的 make targets--build生成Hello.o
target name 隨便
make target 隨便
命令默認就可以
b:將wingw/bin下的g++考到 剛才生成的Hello.o同級目錄下,然后在命令行里切換到Hello.o所在的目錄
執行命令,注意參數(我的java目錄D:\Program Files\Java\):
g++ -I"D:\Program Files\Java\jdk1.6.0_10\include" -Wl,--add-stdcall-alias -shared -o Hello.dll Hello.o
6:運行:
將剛才生成的dll文件拷貝到java工程的根目錄下,運行Hello.class即可
注意:如果測試類是在某個包下的話,例如:com.test.Hello,那我們編譯class文件的時候: javac com\test\Hello.java
然后: javah com.test.Hello,這樣生成的頭文件中的方法在被調用的時候才能找到。
二:java調用so(C)
java和c / c++通信都可以通過jni來實現。 在java代碼中:
System.loadLibrary("Hello");
Hello不能寫成Hello.dll或者Hello.so,它會根據系統平台自動填充,需要注意的是在unix/linux下生成.so動態庫文件的時候,
需要在Hello.so前添加lib,否則找不到.so文件(libHello.so),運行的時候需要指定.so的路徑:
java -Djava.library.path=/homw/user/so所在目錄 -jar Hello.jar
三:命令整理:
以c為例(如果是c++,則把gcc改成g++就OK):
1:在unix/linux環境下
1.1:生成.o文件
gcc -I/usr/lib/j2sdk1.5-ibm/include -fPIC -c example.c
1.2:生成動態庫.so文件
gcc -shared -WI -soname example.o -o libexample.so
2:在windows環境下
2.1:生成.o文件
gcc -c -I"D:\Program Files\Java\jdk1.6.0_10\include" -I"D:\Program Files\Java\jdk1.6.0_10\include\win32" -o Hello.o Hello.c
2.2:生成dll文件
gcc -I"D:\Program Files\Java\jdk1.6.0_10\include" -Wl,--add-stdcall-alias -shared -o Hello.dll Hello.o
由於時間關系,寫得比較亂,o(∩_∩)o...