JNI共享库中的未定义符号,可执行文件正在运行

时间:2013-03-22 18:37:25

标签: c++ c linker makefile java-native-interface

对于C ++,我真的很缺乏经验,所以我希望这只是一个导致此错误的小错误。很抱歉,这篇文章很长,但我试图包含所有重要的细节。

所以这就是我要做的事情:我正在使用一个外部库,它以两个文件夹的形式出现,每个文件夹都有一个makefile。我正在尝试使用一个额外的cpp文件和.h文件中的JNI头创建一个JNI库。

所以文件夹结构是这样的: - > libcds / src和一个创建libcds.a的makefile - > SSA2带有创建SSA.a的makefile - > 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
           你_ZNSo5flushEv
           U _ZNSo9_M_insertImEERSoT_
           U _ZNSt8ios_base4InitC1Ev
           U _ZNSt8ios_base4InitD1Ev
           你_ZSt16__ostream_insertIcSt11char_traitsIcEERSt13basic_ostreamIT_T0_ES6_PKS3_i
           你_ZSt16__throw_bad_castv
           你_ZSt4cout

     

使用--demangle它看起来像这样:000131b0 W   wt_coder ::〜wt_coder()
           U std :: ctype :: _ M_widen_init()const
           U std :: ostream :: put(char)
           U std :: ostream :: flush()
           U std :: ostream&amp; std :: ostream :: _ M_insert(unsigned long)
           U std :: ios_base :: Init :: Init()
           U std :: ios_base :: Init :: ~Init()
           U std :: basic_ostream&gt;&amp;的std :: __ ostream_insert

     
    

(std :: basic_ostream&gt;&amp;,char const *,int)              U std :: __ throw_bad_cast()
             U std :: cout

  

所以实际上这可能与Linker error: undefined reference to `std::ctype<char>::_M_widen_init()

有关

2 个答案:

答案 0 :(得分:1)

我认为您没有链接到C ++标准库。你需要它,因为你链接的一个库是C ++。

在第一种情况下(目标test_index),一切正常,因为您使用g++进行编译和链接,它将隐式链接到libstdc ++。在共享库的情况下,您要链接ld,它不会隐式链接libstdc ++。

您可以使用g++编译和链接共享库,或者使用-lstdc++显式添加libstdc ++。要么应该工作。

答案 1 :(得分:0)

所以问题最终变得非常简单: 我不得不使用g ++来创建库,而不是ld