前面两篇中,已经介绍过如何搭建jni环境以及编写自己的一个jni调用(包括引入第三方类库 如openssl)
Jni:使用openssl库进行rsa加密解密 (环境搭建篇)
Jni:使用openssl库进行rsa加密解密(实现篇)
下面我们要说的是,如何在linux下面编译出我们需要的c++类库,也就是 libxxx.so的so文件 (这里注意,我们用到的文件是一定要以 lib开头的)
例如我们需要加载的是 System.loadLibrary(“MyJni”) 那么这个文件在linux下面的文件名称应该是 libMyJni.so,这里就不再做过多的介绍了。
我们以CentOS 7系统为例子。
编译文件
这里先编译出我们需要的 .o文件
例如,我们这里有三个cpp文件,分别是 1.cpp 2.cpp 3.cpp
其中 3需要调用2 2需要调用1,所以,我们的编译顺序应该是 1 -> 2 -> 3
前提说明 我的java_home以及openssl库分别如下
编译命令
g++ -fpic -I/opt/java/jdk1.8.0_191/include \
-I/opt/java/jdk1.8.0_191/include/linux \
-I/usr/include/openssl \
-L/usr/lib64 -lssl -lcrypto \
-std=gnu++0x \
-c 1.cpp 2.cpp 3.cpp
然后,命令正常运行的话,就会发现有三个 .o文件 分别是 1.o 2.o 3.o
接着 我们编译出.so文件
g++ -shared \
-L/usr/lib64 -lssl -lcrypto \
-o libMyJni.so 1.o 2.o 3.o
之后,我们目录下就会出现 libMyJni.so文件。放到 /usr/lib下面,就可以通过 System.loadLibrary(“MyJni”)来进行加载了。当然,前面已经说了,这里的loadLibrary其实加载的是 java.library.path下面的,所以你随便放到里面一个,甚至是你自己指定该值的目录位置,都可以。
遇到的坑
之前我遇到一个坑,编译出来的so文件放到对应的位置后,发现有这样的一个错误
java: symbol lookup error: /usr/lib64/libMyJni.so: undefined symbol: BIO_new_mem_buf
类似这种的 java: symbol lookup error xxx undefined symbol: xxx 的出现原因,其实就是在编译出so文件的那一步,没有加上对应的 -l参数。也就是我上面的 “-L/usr/lib64 -lssl -lcrypto” .
第一次写那么长篇的,不足之处请多多见谅,也请指出错误或者不足之处。
如有问题可以留言讨论。