簡體   English   中英

JNI共享庫中的未定義符號,可執行文件正在運行

[英]Undefined symbol in shared library for JNI, executable is working

對於C ++,我真的沒有經驗,所以我希望這只是一個導致該錯誤的小錯誤。 抱歉,帖子這么長,但我嘗試提供所有重要細節。

因此,這就是我想要做的事情:我正在使用一個外部庫,該庫以兩個文件夾的形式出現,每個文件夾都有一個makefile。 我試圖用一個附加的cpp文件和一個.h文件中的JNI標頭創建一個JNI庫。

因此,文件夾結構是這樣的:-> libcds / src,帶有創建libcds.a的makefile
->具有創建SSA.a的makefile的SSA2
-> myFolder,其中包含我的cpp和h文件以及應創建庫的makefile

所以這是不同的makefile:

libcds / src目錄:

CPP=g++

CPPFLAGS=-O9 -w -DNDEBUG 

INCL=-I../includes/

CODERS_DIR=coders
CODERS_OBJECTS=$(CODERS_DIR)/huff.o $(CODERS_DIR)/huffman_codes.o

STATIC_PERMUTATION_DIR=static_permutation
STATIC_PERMUTATION_OBJECTS=$(STATIC_PERMUTATION_DIR)/perm.o ...

STATIC_BITSEQUENCE_DIR=static_bitsequence
STATIC_BITSEQUENCE_OBJECTS=$(STATIC_BITSEQUENCE_DIR)/static_bitsequence.o ..

STATIC_SEQUENCE_DIR=static_sequence
STATIC_SEQUENCE_OBJECTS=$(STATIC_SEQUENCE_DIR)/static_sequence.o, ..., wt_coder.o

UTILS_DIR=utils
UTILS_OBJECTS=$(UTILS_DIR)/alphabet_mapper_none.o $(UTILS_DIR)/alphabet_mapper.o

%.o: %.cpp

$(CPP) $(CPPFLAGS) $(INCL) -c $< -o $@

all: lib 

lib: pre $(CODERS_OBJECTS) $(STATIC_BITSEQUENCE_OBJECTS) $(STATIC_SEQUENCE_OBJECTS) $(UTILS_OBJECTS) $(STATIC_PERMUTATION_OBJECTS)
    ar rcs ../lib/libcds.a $(CODERS_OBJECTS) $(STATIC_BITSEQUENCE_OBJECTS) $(STATIC_SEQUENCE_OBJECTS) $(UTILS_OBJECTS) $(STATIC_PERMUTATION_OBJECTS)

pre:
    cp basics.h ../includes/
    cp */*.h ../includes/

SSA2:

CC=g++

CFLAGS=-w -O9 -DNDEBUG -I../libcds/includes/
CODERS_DIR=../libcds/src/coders

CODERS_OBJECTS=$(CODERS_DIR)/huff.o $(CODERS_DIR)/huffman_codes.o

STATIC_BITSEQUENCE_DIR=../libcds/src/static_bitsequence

STATIC_BITSEQUENCE_OBJECTS=$(STATIC_BITSEQUENCE_DIR)/static_bitsequence.o ...

STATIC_SEQUENCE_DIR=../libcds/src/static_sequence

STATIC_SEQUENCE_OBJECTS=$(STATIC_SEQUENCE_DIR)/static_sequence.o ...

UTILS_DIR=../libcds/src/utils

UTILS_OBJECTS=$(UTILS_DIR)/alphabet_mapper_none.o $(UTILS_DIR)/alphabet_mapper.o

all: index

# pattern rule for all objects files

%.o: %.c *.h

    $(CC) -c $(CFLAGS) $< -o $@

%.o: %.cpp *.h

    $(CC) -c $(CFLAGS) $< -o $@

index: bitrankw32int.o bitarray.o  ds/ds.o ds/globals.o ds/helped.o ds/shallow.o ds/deep2.o ds/blind2.o SSA.o

    cp ../libcds/lib/libcds.a SSA.a

    ar rcs SSA.a SSA.o bitrankw32int.o bitarray.o ds/ds.o ds/globals.o ds/shallow.o ds/helped.o ds/deep2.o ds/blind2.o

我的makefile:

CC=g++ -I $(JAVA_HOME)/include -I $(JAVA_HOME)/include/linux
LD_LIBRARY_PATH=./
JNI_NAME= indexlib

all: test

%.o: %.c *.h
    $(CC) -c $(CFLAGS) $< -o $@

test_index: 
    $(CC) run_queries.c -o testIndex SSA.a

test_index_lib: run_queries.o
    ld -shared -soname lib$(JNI_NAME).so -o lib$(JNI_NAME).so run_queries.o SSA.a -lc

可執行文件testIndex可以正常工作。 但是,生成的庫無法通過錯誤消息由Java加載:

未定義的符號:_ZNSt8ios_base4InitC1Ev

當我使用nm查找該符號時,得到以下結果:

000131b0 W _ZN8wt_coderD2Ev
U _ZNKSt5ctypeIcE13_M_widen_initEv
U _ZNSo3putEc
U _ZNSo5flushEv
U _ZNSo9_M_insertImEERSoT_
U _ZNSt8ios_base4InitC1Ev
U _ZNSt8ios_base4InitD1Ev
U _ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i
U _ZSt16__throw_bad_castv
U _ZSt4cout

使用--demangle看起來像這樣:000131b0 W wt_coder ::〜wt_coder()
U std :: ctype :: _ M_widen_init()常量
U std :: ostream :: put(char)
U std :: ostream :: flush()
U std :: ostream&std :: ostream :: __ M_insert(無符號長)
U std :: ios_base :: Init :: Init()
U std :: ios_base :: Init ::〜Init()
U std :: basic_ostream>&std :: __ ostream_insert

(std :: basic_ostream>&,char const *,int)U std :: __ throw_bad_cast()
U std :: cout

所以實際上這可能與鏈接器錯誤有關:對`std :: ctype <char> :: __ M_widen_init()的未定義引用

我認為您沒有鏈接到C ++標准庫。 您需要它,因為要鏈接的庫之一是C ++。

在第一種情況下(目標test_index),一切正常,因為您正在使用g++進行編譯和鏈接,並且它將隱式鏈接到libstdc ++。 在共享庫的情況下,您將與ld鏈接,而ld不會隱式鏈接libstdc ++。

您可以使用g++編譯和鏈接共享庫,也可以使用-lstdc++顯式添加libstdc -lstdc++ 兩者都應該起作用。

因此問題最終變得非常簡單:我必須使用g ++來創建庫,而不是ld

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM