java調用dll或so動態庫文件(c++/c)
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爲例
Java代碼
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內容:
C++代碼
/* 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內容:
C++代碼
#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
歡迎關注本站公眾號,獲取更多信息