linux下 java JNI调用C语言动态链接库

简介: 今天花了至少3个小时跑这个java调c的动态链接库的Hello,native world的程序。把所有犯的错误和要点总结一下!1 java 中 c语言函数的声明    public native static void greeting(); //就像是接口声明一样,不过有native!2 编译 javac HelloNative.

今天花了至少3个小时跑这个java调c的动态链接库的Hello,native world的程序。
把所有犯的错误和要点总结一下!
1 java 中 c语言函数的声明
    public native static void greeting(); //就像是接口声明一样,不过有native!
2 编译 javac HelloNative.java ,然后使用 javah
javah HelloNative会自动产生c的头文件HelloNative.h
3 生成的头文件 的 第一句子为
  #include
  但是gcc里面默认环境可不知道jni.h是什么东西,jni.h在jdk的$JAVA_HOME/include或者$JAVA_HOME/include/linux下面,可进去查看一下~
4 接下来就是根据HelloNative.h中声明的方法写C语言的实现,注意,自动生成的那个函数名字很长,并且 开头的  Java是大写的,大小写很致命,(最后我的程序在动态库已经加载好的情况下报错:java.lang.UnsatisfiedLinkError: HelloNative.greeting()V,就是因为c语言中的函数名字大小写写错,奇怪!编译不报错.....)
5 linux下编译生成动态库,注意不同环境的不一样~
gcc -fPIC -I jdk/include -I jdk/include/linux -shared -o libHelloNative.so HelloNative.c
  在这里,我犯的错:

a,不理解 -I jdk -I 是include,显示指定库的库的地址,自然后面的jdk是要用你的设计地址替换的
b, 着急的去网上搜索问题,没有注意的在linux下,动态链接库的名字 必须是 lib****.so,必须以lib开头!
6 编译生成了 libHelloNative.h之后,接下写一个test类,如 HelloNativeTest,
当然要调用System.loadLibrary("HelloNative");注意此时不要lib,也不要.so!;
调用执行 HelloNative.greeting();这个时候错误又来了:
java.lang.UnsatisfiedLinkError: no HelloNative in java.library.path。这个错误很经典,原因:是java找不到库路径~:
显然: libHelloNative.so放在当前路径 ".",只linux执行的时候却不知道在当前路径找。 linux很“傻”很“复杂”~
a. linux下面java.library.path 和环境变脸 jdk/bin的那个个PATH不是一回事情,有另外一个默认变量 LD_LIBRARY_PATH来保存他的信息。而windows下,首先java会找当前目录,其次,它会去环境变量的地址找!
b。 由于linux的路径特殊,所以,解决方法 1-可以调用sysout(System.getProperty("java.library.path"));来查看! 然后把 libXXXX.so拷贝到那里面的目录下去
2 设置环境变量 export LD_LIBRARY_PATH=.:$LD_LIBRARY_PATH ,但是设置到哪里呢? /etc/profile ? or /root/.bashrc 不知道...忘记了linux的加载顺序了~
3 可以单次执行时候指定library位置:
  java -Djava.library.path=. HelloNativeTest
总结犯错:1不知道gcc编译时候指定库 2 不了解java.libray.path的特点,特别是砸linux下 3 c语言实现函数的时候拼写错误 4 排除问题不够理性,系统化,出现了烦躁情绪,导致效率低。 时刻明白,机器只是做你指定的事情,总是你自己出错了~~~
附:gcc 参数解释(转载):
   最主要的是GCC命令行的一个选项:
-shared 该选项指定生成动态连接库(让连接器生成T类型的导出符号表,有时候也生成弱连接W类型的导出符号),不用该标志外部程序无法连接。相当于一个可执行文件
l -fPIC:表示编译为位置独立的代码,不用此选项的话编译后的代码是位置相关的所以动态载入时是通过代码拷贝的方式来满足不同进程的需要,而不能达到真正代码段共享的目的。
l -L.:表示要连接的库在当前目录中
l -ltest:编译器查找动态连接库时有隐含的命名规则,即在给出的名字前面加上lib,后面加上.so来确定库的名称
l LD_LIBRARY_PATH:这个环境变量指示动态连接器可以装载动态库的路径。
l 当然如果有root权限的话,可以修改/etc/ld.so.conf文件,然后调用 /sbin/ldconfig来达到同样的目的,不过如果没有root权限,那么只能采用输出LD_LIBRARY_PATH的方法了。
4、注意
调用动态库的时候有几个问题会经常碰到,有时,明明已经将库的头文件所在目录 通过 “-I” include进来了,库所在文件通过 “-L”参数引导,并指定了“-l”的库名,但通过ldd命令察看时,就是死活找不到你指定链接的so文件,这时你要作的就是通过修改LD_LIBRARY_PATH或者/etc/ld.so.conf文件来指定动态库的目录。通常这样做就可以解决库无法链接的问题了。
文章来自: 好喜爱学习网(http://www.haoxiai.net) 网址:http://www.haoxiai.net/caozuoxitong/linux/5227.html

目录
相关文章
|
2月前
|
安全 druid Java
Java 访问数据库的奇妙之旅
本文介绍了Java访问数据库的几种常见方式
56 12
|
4月前
|
Java BI API
Java Excel报表生成:JXLS库的高效应用
在Java应用开发中,经常需要将数据导出到Excel文件中,以便于数据的分析和共享。JXLS库是一个强大的工具,它基于Apache POI,提供了一种简单而高效的方式来生成Excel报表。本文将详细介绍JXLS库的使用方法和技巧,帮助你快速掌握Java中的Excel导出功能。
143 6
|
4月前
|
分布式计算 Java Hadoop
linux中HADOOP_HOME和JAVA_HOME删除后依然指向旧目录
通过以上步骤,可以有效地解决 `HADOOP_HOME`和 `JAVA_HOME`删除后依然指向旧目录的问题。确保在所有相关的配置文件中正确设置和删除环境变量,并刷新当前会话,使更改生效。通过这些措施,能够确保系统环境变量的正确性和一致性。
61 1
|
5月前
|
算法 Java Linux
java制作海报七:java Graphics2D 合成图片 在 linux下中文不显示,echarts图上的中文也不显示问题
这篇文章讨论了在Linux环境下使用Java Graphics2D合成图片时遇到的中文显示问题,并提供了解决方案,包括如何在Linux系统中添加中文字体库。
81 1
java制作海报七:java Graphics2D 合成图片 在 linux下中文不显示,echarts图上的中文也不显示问题
|
4月前
|
Java API Apache
|
5月前
|
JSON JavaScript Java
在Java中处理JSON数据:Jackson与Gson库比较
本文介绍了JSON数据交换格式及其在Java中的应用,重点探讨了两个强大的JSON处理库——Jackson和Gson。文章详细讲解了Jackson库的核心功能,包括数据绑定、流式API和树模型,并通过示例演示了如何使用Jackson进行JSON解析和生成。最后,作者分享了一些实用的代码片段和使用技巧,帮助读者更好地理解和应用这些工具。
470 0
在Java中处理JSON数据:Jackson与Gson库比较
|
5月前
|
运维 Java Linux
【运维基础知识】Linux服务器下手写启停Java程序脚本start.sh stop.sh及详细说明
### 启动Java程序脚本 `start.sh` 此脚本用于启动一个Java程序,设置JVM字符集为GBK,最大堆内存为3000M,并将程序的日志输出到`output.log`文件中,同时在后台运行。 ### 停止Java程序脚本 `stop.sh` 此脚本用于停止指定名称的服务(如`QuoteServer`),通过查找并终止该服务的Java进程,输出操作结果以确认是否成功。
232 1
|
5月前
|
算法 Java Linux
java制作海报五:java 后端整合 echarts 画出 折线图,项目放在linux上,echarts图上不显示中文,显示方框口口口
这篇文章介绍了如何在Java后端整合ECharts库来绘制折线图,并讨论了在Linux环境下ECharts图表中文显示问题。
116 1
|
5月前
|
Java Linux Maven
用sdkman在linux上管理多个java版本
本文介绍了如何在Linux上使用SDKMAN来管理多个Java版本,包括安装SDKMAN、验证安装、列出和安装不同版本的JDK、Maven和Gradle,以及如何切换使用不同版本。
195 0
|
5月前
|
JSON Java 数据格式
Java Jackson-jr库使用介绍
Jackson-jr是专为资源受限环境设计的轻量级JSON处理库,适用于微服务、移动应用及嵌入式系统。它通过牺牲部分高级功能实现了更小体积和更快启动速度,非常适合对库大小敏感的项目。本文将介绍如何使用Jackson-jr进行JSON序列化与反序列化,并演示处理嵌套对象与数组的方法。此外,还介绍了自定义序列化与反序列化的技巧以及性能与功能的权衡。通过示例代码,展示了Jackson-jr在常见任务中的高效与灵活性。
58 0