背景:利用c++编写了一个图片质量检测的代码,调用到了opencv,目前需要在linux下调用c++编译得到的.so文件,在java上进行部署运行。
在上一篇博客中已经详细介绍了如果编译并且调用.so文件,只是还未编译成功。经过这么多天的努力终于弄明白的整个流程,并且知道错误在哪儿了。
生成.so文件并调用
1.编译java并生成头文件
javac hello/hellojni.java
javah hello.hellojni
执行完上述代码后在/src目录下会生成一个hello_hellojni.h头文件,我们编写的c++代码中要调用这个头文件,并且将函数复制到cpp文件中进行编写代码。
2.编译c++程序并生成.so文件
上一篇博客中是利用gcc编译的,本篇则利用g++编译。
g++ -I"/$你jdk的安装路径$/include" -I"/$你jdk的安装路径$/include/linux" -fPIC -shared -0 libxxx.so check.cpp `pkg-config --cflags --libs opencv`
注: check.cpp是c++的主程序。上面g++命令坑太多了,如pkg-config --cflags --libs opencv
前后的符号是Esc下面的那个符号,而且这句命令如果直接放在了g++的后面,编译是会不成功的,即使成功了,到后面调用这个.so文件时,Java程序也会出现无法调用opencv的情况,但是放在最后便成功了,就这个问题卡了我3天!!!
接下来是路径问题,libxxx.so需要放到java.library.path(Java的library路径下),接下来会有2种方法,但是个人推荐第一种方法。
1).直接复制到java.library.path下
#一般默认的路径是/usr/lib
sudo cp libxxx.so /usr/lib
这样较为方便,且c++代码中调用到的opencv库中的.so文件也都在该路径下,不需要你再做调整。
2).将java的library路径自己临时设置一下
export在当然shell下有效,将路径设为当前路径(为libxxx.so所在的路径)。
export LD_LIBRARY_PATH=.
改方法有个缺点,即后面调用.so文件时存在调用第三方库时,需要将第三方库也复制到该目录下。不然会出现无法调用第三方库的.so文件的情况。
接下来就可以直接运行Java函数调用.so文件了(当然也可以直接在idea中run,绿色的小按钮):
java hello.hellojni
问题
当出现如上所示的问题时,基本就是路径问题,如图是java找不到libpicture_check.so,需要回顾上面路径的问题。
有一个写了一个小栗子的博客很好,可以跟着复现一下:小栗子
在java调用.so文件时,可能会出现类型转换问题,可以参考这一篇博客:类型转换