• 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 FilesMinGWin   
      C_INCLUDE_PATH:  D:Program FilesMinGWinclude 
      CPLUS_INCLUDE_PATH:  D:Program FilesMinGWincludec++3.4.5;D:Program FilesMinGWincludec++3.4.5mingw32;D:Program                        FilesMinGWincludec++3.4.5ackward;D:Program FilesMinGWinclude 
      LIBRARY_PATH:   D:Program FilesMinGWlib 

      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.   
    3. public native void sayHello();  
    4.   
    5. static{  
    6.     System.loadLibrary("Hello");  
    7. }  
    8.   
    9.   
    10. public static void main(String[] args){  
    11.     Hello h = new Hello();  
    12.     h.sayHello();  
    13. }  

    然后编译生成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 FilesJavajdk1.6.0_10includewin32 -LD:Program FilesJavajdk1.6.0_10include -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++代码  收藏代码
    1.         /* DO NOT EDIT THIS FILE - it is machine generated */  
    2. #include <jni.h>  
    3. /* Header for class Hello */  
    4.   
    5. #ifndef _Included_Hello  
    6. #define _Included_Hello  
    7. #ifdef __cplusplus  
    8. extern "C" {  
    9. #endif  
    10. /* 
    11.  * Class:     Hello 
    12.  * Method:    sayHello 
    13.  * Signature: ()V 
    14.  */  
    15.     int main() ;  
    16.       
    17.       
    18. JNIEXPORT void JNICALL Java_Hello_sayHello  
    19.   (JNIEnv *, jobject);  
    20.   
    21. #ifdef __cplusplus  
    22. }  
    23. #endif  
    24. #endif  

    修改后的Hello.cpp内容: 
    C++代码  收藏代码
    1. #include <iostream>    
    2. #include "Hello.h"   
    3. using namespace std;      
    4.   
    5. int main()      
    6.      {   
    7.     return 1;  
    8.      }  
    9.   
    10.   
    11. JNIEXPORT void JNICALL Java_Hello_sayHello(JNIEnv *, jobject){  
    12.     printf("Hello world! ");  
    13.     return ;  
    14. }  

    a:然后用eclipse c++插件的 make targets--build生成Hello.o 
    target name 随便 
    make target 随便 
    命令默认就可以 
       b:将wingw/bin下的g++考到 刚才生成的Hello.o同级目录下,然后在命令行里切换到Hello.o所在的目录 
       执行命令,注意参数(我的java目录D:Program FilesJava): 
       g++ -I"D:Program FilesJavajdk1.6.0_10include"  -Wl,--add-stdcall-alias -shared -o Hello.dll Hello.o   
       
      6:运行: 
        将刚才生成的dll文件拷贝到java工程的根目录下,运行Hello.class即可 


      注意:如果测试类是在某个包下的话,例如:com.test.Hello,那我们编译class文件的时候: javac com estHello.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 FilesJavajdk1.6.0_10include" -I"D:Program FilesJavajdk1.6.0_10includewin32" -o Hello.o Hello.c 
      2.2:生成dll文件 
      gcc -I"D:Program FilesJavajdk1.6.0_10include" -Wl,--add-stdcall-alias -shared -o Hello.dll Hello.o 

    由于时间关系,写得比较乱,o(∩_∩)o...
  • 相关阅读:
    NOIP 转圈游戏
    NOIP 2012 同余方程
    BZOJ3864 Hero meet devil
    HDU3045 Picnic Cows
    「PKUWC2018」随机算法
    CF543E Listening to Music
    CF833E Caramel Clouds
    「PKUWC2018」Slay the Spire
    Luogu2183【国家集训队】礼物
    CF932E Team Work
  • 原文地址:https://www.cnblogs.com/wxmdevelop/p/4172433.html
Copyright © 2020-2023  润新知