jni程序,关于某些.so,.a库的依赖性。但是loadlibrary func只能链接动态库,而静态库又如何

时间:2018-12-28 03:44:48

标签: java linux

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

我使用静态库来构建动态库,然后在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("world\n");
 cout<<"hahaha\n";
 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 leveldb7Options 结果:

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程序找不到相同的符号。 我想知道原因和正确的方法。

1 个答案:

答案 0 :(得分:0)

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

对于Java,这意味着您需要将其与class EmailClient: imap_host = 'imap.gmail.com' imap_user = 'test@test.com' imap_pass = 'password' def process_mailbox(M): diction = [] rv, data = M.search(None, "ALL") if rv != 'OK': print('No messages found!') return for num in data[0].split(): rv, data = M.fetch(num, '(RFC822)') if rv != 'OK': print("ERROR getting message", num) return msg = email.message_from_bytes(data[0][1]) hdr = email.header.make_header(email.header.decode_header(msg['Subject'])) subject = str(hdr) print('Message %s: %s' % (num, subject)) date_tuple = email.utils.parsedate_tz(msg['Date']) if date_tuple: local_date = datetime.datetime.fromtimestamp(email.utils.mktime_tz(date_tuple)) print('Local Date:', local_date.strftime('%a, %d %b %Y %H:%M:%S')) for part in msg.walk(): if part.get_content_type() == 'text/html': print(part.get_payload()) diction.append(part.get_payload()) M = imaplib.IMAP4_SSL('imap.gmail.com') try: rv, data = M.login(imap_user, imap_pass) except imaplib.IMAP4.error: print("LOGIN FAILED!") sys.exit(1) print(rv, data) rv, mailboxes = M.list() if rv == 'OK': print('Mailboxes:') print(mailboxes) rv, data = M.select('Inbox') if rv == 'OK': print('Processing mailbox...\n') process_mailbox(M) M.close() else: print('ERROR: Unable to open mailbox', rv) M.logout() 可执行文件链接。这意味着您每次运行Java应用程序时都需要重新组装它,但这非常不方便。