java调用dll或so动态库文件(c++/c)

java调用dll或so动态库文件(c++/c)

CC#C++JavaEclipse

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代码  

  1. public class Hello {
  2. public native void sayHello();
  3. static{
  4. System.loadLibrary("Hello");
  5. }
  6. public static void main(String[] args){
  7. Hello h = new Hello();
  8. h.sayHello();
  9. }

然后编译生成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++代码  

  1. /* DO NOT EDIT THIS FILE - it is machine generated */
  2. #include <jni.h>
  3. /* Header for class Hello */
  4. #ifndef _Included_Hello
  5. #define _Included_Hello
  6. #ifdef __cplusplus
  7. extern "C" {
  8. #endif
  9. /*
  10. * Class:     Hello
  11. * Method:    sayHello
  12. * Signature: ()V
  13. */
  14. int main() ;
  15. JNIEXPORT void JNICALL Java_Hello_sayHello
  16. (JNIEnv *, jobject);
  17. #ifdef __cplusplus
  18. }
  19. #endif
  20. #endif

修改后的Hello.cpp内容:

C++代码  

  1. #include <iostream>
  2. #include "Hello.h"
  3. using namespace std;
  4. int main()
  5. {
  6. return 1;
  7. }
  8. JNIEXPORT void JNICALL Java_Hello_sayHello(JNIEnv *, jobject){
  9. printf("Hello world!\n");
  10. return ;
  11. }

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...

时间: 2024-10-06 00:31:07

java调用dll或so动态库文件(c++/c)的相关文章

Qt打开外部程序和文件夹需要注意的细节(Qt调用VC写的动态库,VC需要用C的方式输出函数,否则MinGW32编译过程会报错)

下午写程序中遇到几个小细节,需要在这里记录一下. ? 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 QProcess *process = new QProcess(this);     QFileInfo fileinfo(appUrl);     QString appPath = QApplication::applicationDirPath()+SAVEDIR+"/"+fileinfo.fileName();     bool res = proce

Visual Studio中根据系统区分引用64位、32位DLL动态库文件的配置方法

原来使用Win7的32位系统,进行C#工程的开发,后来重装系统,换成了win7的64位系统 调试原来的工程,由于在其中引用了"SQLite"的32位的dll,导致在64为位下程序无法运行(但是编译可以通过) 后来通过修改工程文件(.csproj),在其中设置引用的条件,解决了问题 打开引用了SQLite的工程(例如叫做info)的工程文件(info.csproj),找到对SQLite引用的语句,类似如下的代码 代码如下: <Reference Include="Syst

修改OpenSSL默认编译出的动态库文件名称

在 Windows 平台上调用动态链接库 dll 文件时,有两种方式:a) 隐式的加载时链接:使用 *.lib (导入库)文件,在 IDE 的链接器相关设置中加入导入库 lib 文件的名称,或在程序中加入预编译指令 #pragma comment (lib,”*.lib”).b) 显式的运行时链接.不使用 *.lib (导入库)文件,使用 Load Library(),GetProcAddress() 函数来加载动态库中的函数.要注意的是在导入库 lib 文件内部包含了其对应 dll 文件的名称

python中调用C++写的动态库

一.环境:Windows XP + Python3.2 1. dll对应的源文件(m.cpp): #include <stdio.h> extern "C" { _declspec(dllexport) int add(int a, int b) { return a+b; } _declspec(dllexport) void print_sum(unsigned long ulNum) { while(ulNum != 0) { printf("The ulN

【转】VS2013动态库文件的创建及其使用详解

一.VS2013动态库文件的创建 1.新建项目,win32,win32项目,输入项目名称,例如MakeDll. 2.”确定“——”下一步“,选择”DLL“选项,再点”完成“: 3.菜单栏选择”项目“——>”添加新项“,来创建头文件MakeDll.h. 在MakeDll.h中输入以下例子代码: 1 #ifdef DLL_API//如果已经定义就什么都不做 2 //nothing to do 3 #else //否则定义DLL_API 4 #define DLL_API __declspec(dll

JAVA调用C语言写的SO文件

JAVA调用C语言写的SO文件 因为工作需要写一份SO文件,作为手机硬件IC读卡和APK交互的桥梁,也就是中间件,看了网上有说到JNI接口技术实现,这里转载了一个实例 1 // 用JNI实现 2 // 实例: 3 4 // 创建HelloWorld.java 5 class HelloWorld 6 { 7 private native void print(); 8 public static void main(String[] args) 9 { 10 new HelloWorld().p

linux下把log4cxx封装成so动态库文件(一)

这是一个经常遇到的问题,在软件开发过程中,需要将某些功能封装成一个独立的模块,这样维护升级也很方便.现在我们就要把开源日志库log4cxx封装成so动态加载库文件. 在上一篇文章<log4cxx日志库RedHat下安装>中,我们已经将log4cxx安装在home/mac/log4cxx/log4cxx下了,那么接下来的操作我们就继续在这个路径下进行. 还是先tree一下/home/mac/log4cxx这个目录吧 log4cxx ---apr ---apr-util ---log4cxx 那再

Makefile 编译动态库文件及链接动态库

本文为原创文章,转载请指明该文链接 文件目录结构如下 1 dynamiclibapp.c 2 Makefile 3 comm/inc/apue.h 4 comm/errorhandle.c 5 dynamiclib/Makefile 6 dynamiclib/dynamiclib_add.c 7 dynamiclib/dynamiclib_mul.c 8 dynamiclib/inc/dynamiclibs.h 9 dynamiclib/libs/ 1. dynamiclib目录 dynamic

Java 调用Dll

Java 中怎么能调用到dll中的函数呢? 关键是java中生的本地函数名参数和dll中的本地函数名参数一模一样. 这个程序是java中调用dll中的求和函数. 一,java代码部分操作 1.新建工程 2.DllTest.java代码 package com.aizizai.calldll; public class DllTest { static { System.loadLibrary("hellodll"); } public static native int sum(int