comes from: http://watershitter.iteye.com/blog/477615
1 java 中 c语言函数的声明
public native static void greeting(); //就像是接口声明一样,不过有native!2 编译 javac HelloNative.java ,然后使用 javah
javah HelloNative会自动产生c的头文件HelloNative.h
3 生成的头文件 的 第一句子为
#include <jni.h>4 接下来就是根据HelloNative.h中声明的方法写C语言的实现,注意,自动生成的那个函数名字很长,并且 开头的 Java是大写的,大小写很致命,(最后我的程序在动态库已经加载好的情况下报错:java.lang.UnsatisfiedLinkError: HelloNative.greeting()V,就是因为c语言中的函数名字大小写写错,奇怪!编译不报错.....)
<<<评论:这个作者有点2,直接复制就好了>>>
gcc -fPIC -I jdk/include -I jdk/include/linux -shared -o libHelloNative.so HelloNative.c
<<<我当时的编译命令是:
gcc -fPIC -shared -D_REENTRANT -I $JAVA_HOME/include -I $JAVA_HOME/include/linux Hello.c -o libTestHello.so
我认为作者的命令是出问题的,除非作者真有jdk这个文件夹而且真在他的父母录。。。我这条前提也是配置了java环境,不过这不是废话么。。>>>
在这里,我犯的错:
a,不理解 -I jdk -I 是include,显示指定库的库的地址,自然后面的jdk是要用你的设计地址替换的,
b, 着急的去网上搜索问题,没有注意的在linux下,动态链接库的名字 必须是 lib****.so,必须以lib开头!
<<<我也被b这条搞了很长时间,而且我就只是在这里出了问题。。真感谢作者>>>
总结犯错:
1.不知道gcc编译时候指定库
2.不了解java.libray.path的特点,特别是在linux下
3.c语言实现函数的时候拼写错误
4.排除问题不够理性,系统化,出现了烦躁情绪,导致效率低。 时刻明白,机器只是做你指定的事情,总是你自己出错了~~~
当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。
<<<虽然自己当初用过jni(不过貌似是一年前了),如今用起来居然还花了我两个小时去写一个helloworld!!可想我当时的基础多么不扎实,我却一直跟别人说我的基础非常厉害,非常牢固。。真无地自容了>>>
联系客服