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程序找不到相同的符号。 我想知道原因和正确的方法。
答案 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应用程序时都需要重新组装它,但这非常不方便。