jni程序,依赖于一些.so,.a库.但是loadlibraryfunc只能链接动态库,静态库呢



jni需要加载库,并且该库是基于某个静态库的。但是在执行jni时,我得到了静态库中定义的und符号。

我使用静态库来构建动态库,并在java程序中加载动态库。

Makefile:

sudo cp /home/daniel/projects/leveldb/libleveldb.a libleveldb.a
g++ -shared -o libTest.so -fPIC -I/usr/lib/jvm/java-8-oracle/include/ -I/usr/lib/jvm/java-8-oracle/include/linux/ -L. -L/usr/lib/vmware-ovftool/lib/ libleveldb.a -lpthread Test.cpp

Test.cpp:

#include "Test.h"
#include <leveldb/db.h>
#include <iostream>
#include <cstdlib>
using namespace std;
JNIEXPORT void JNICALL Java_Test_getStringFromC(JNIEnv *, jobject)
{
printf("worldn");
cout<<"hahahan";
leveldb::DB *db = nullptr;
leveldb::Options options;
options.create_if_missing = true;
leveldb::Status status = leveldb::DB::Open(options, "/tmp/testdb",&db);
...

cmd:java测试结果:

java: symbol lookup error: /usr/lib/libTest.so: undefined symbol: _ZN7leveldb7OptionsC1Ev

cmd:readelf-s libleveldb.a|grep leveldb7选项结果:

169: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _ZN7leveldb7OptionsC1Ev
109: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _ZN7leveldb7OptionsC1Ev
48: 0000000000000000     0 NOTYPE  GLOBAL DEFAULT  UND _ZN7leveldb7OptionsC1Ev
8: 0000000000000000   108 FUNC    GLOBAL DEFAULT    1 _ZN7leveldb7OptionsC2Ev
12: 0000000000000000   108 FUNC    GLOBAL DEFAULT    1 _ZN7leveldb7OptionsC1Ev

这意味着,我可以在静态库中找到符号,但在基于libleveldb.a的动态库中,jni程序找不到相同的符号。我想知道原因和正确的方式来完成它。

要使用静态库,需要将其与可执行文件静态链接。

在Java的情况下,这意味着您需要将其与java可执行文件链接。这意味着每次运行Java应用程序时都需要重新组装它,但这将非常不方便。

最新更新