zoukankan      html  css  js  c++  java
  • cygwin+windows 使用JNI时 .c文件打包成.so

    写一个JNI Test.

    1、java中声明 native func
    2、使用javah 将.class编译得到 .h
    3、编写.c
    4、打包成.so 动态库
    5、JAVA中使用加载.so 然后就可以使用native方法了。
     
    其他步骤问题不大,在打包上卡住了。
    一个helloWorld打包的话,只需要
    -------------------------------------
    1: gcc -c helloWorld -o hello.o
    2: gcc -shared libhello.so hello.o
    ------------------------------------
     
    但是完成一个简单的JNI程序,并可以在JAVA中调用 远不止这些。
    只记录需要注意的。
    生成.o时
    1、是JNI程序,所以 C文件中包含了 所以打包时要包含jni.h的目录。jni.h是JDK中的文件。
    如:加入选项(路径指向jni根目录和win32目录)
    -I"/cygdrive/f/Program Files/Java/jdk1.6.0_21/include" 
    -I"/cygdrive/f/Program Files/Java/jdk1.6.0_21/include/win32" 
    2、要加入 -D__int64="long long"  不然会报错。"=".""之类的错误信息。
    .o生成.so时 
    1、假如选项 --kill-at,如果不加在java中使用.so文件时,可能会报找不到某方法。
           使用dllexp等动态库查看器,可以看到 没使用选项时动态库里的方法名字是 testfunc@8 ,加了之后是 testfunc。 少了@符号。
    2、使用cygwin生成出来可能需要 cygwin1.dll这个动态库才能运行。
    使用命令 ldd XXXX.so 可以查看其依赖的库,如我的
        ------------------------------------------------------
    $ ldd libtest.so
            ntdll.dll => /cygdrive/c/WINDOWS/system32/ntdll.dll (0x7c920000)
            kernel32.dll => /cygdrive/c/WINDOWS/system32/kernel32.dll (0x7c800000)
            cygwin1.dll => /cygdrive/f/workspace/TestJNI/libs/cygwin1.dll (0x61000000)
    ---------------------------------------------------------
    这样的话,使用java导入我们自己的XXXX.so时,就必须先导入cygwin1.dll这个依赖库。
    或者 使用选型 -mno-cygwin(在生成.so时使用)但在cygwin下使用这个命令有个问题。
    可能会出现
    cc: The -mno-cygwin flag has been removed; use a mingw-targeted cross-compiler 错误
    因为gcc4(暂时)不支持这个参数
    只要运行 usr/bin/set-gcc-default-3.sh  将gcc运行的版本改为gcc-3即可。如果要变回来
    usr/bin/set-gcc-default-4.sh
    或者装个MSYS使用mingw编译
    综上所述,命令应该是
    ------------------------------------------------------
    gcc -D__int64="long long"
    -I"/cygdrive/f/Program Files/Java/jdk1.6.0_21/include"
    -I"/cygdrive/f/Program Files/Java/jdk1.6.0_21/include/win32"
    -c -o test.o tun_test_JNI_C2JAVA.c
     
    /usr/bin/set-gcc-default-3.sh 
     
    cc -shared -o libtest.so -Wl,-soname,libtest.so,--kill-at test.o -mno-cygwin
    -------------------------------------------------------
    这样就可以生成出一个正确的.so文件了。
     
    离在JAVA中正常使用,还差最后一步了。
    在JAVA中导入动态链接库,如果总是出现 
    java.lang.UnsatisfiedLinkError: no XXXX in java.library.path” 继续往下看。

    JAVA中使用动态链接库须知 http://www.cnblogs.com/xifanyaoyao/p/3659002.html

  • 相关阅读:
    os.path.split()、os.path.realpath()和os.path.join()
    我终于也有了自己的博客网站
    (Bug修复)C#爬虫,让你不再觉得神秘
    DevExpress弹框、右键菜单、Grid的使用
    Linux 宝塔部署 ASP.NET Core 应用
    C#高级特性(反射)
    WPF 的内部世界(Binding)
    WPF 的内部世界(控件与布局)
    Layui事件监听(表单和数据表格)
    (待更新)tensorboard [Fatal error in launcher: Unable to create process using]
  • 原文地址:https://www.cnblogs.com/xifanyaoyao/p/3659000.html
Copyright © 2011-2022 走看看