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 `[email protected]‘
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
由于时间关系,写得比较乱,o(∩_∩)o...