在工程中用到使用Python调用C++编写的动态库,结果报如下错误:
OSError: ./extract_str.so: undefined symbol: _ZNSt8ios_base4InitD1Ev
Python调用函数
1 #coding:utf-8 2 from ctypes import * 3 4 libpcre = cdll.LoadLibrary("./extract_str.so") 5 pcre="^GirlFriends+Servers+d+x2Ed+s+x2Es+ports+d" 6 ret = libpcre.extract_exact_strings(pcre, len(pcre), 4, max_str, max_str_len, expr_str, expr_str_len) 7 if ret == 1: #解析成功 8 print(ret) 9 print(max_str) 10 print(expr_str) 11 else: #解析失败 12 print("ret is not 1!")
加载目录文件
报错:
执行nm命令
通过搜索知道ios_base4Init 是C++标准输入输出函数库,说明该库未被加载。搜索知道是由于链接的问题。
Stackoverflow链接:http://stackoverflow.com/questions/10906275/undefined-reference-to-stdios-baseinitinit
查看Makefile
1 CC = gcc 2 CCC = g++ 3 CFLAGS = -g -Wall $(OPEN_O2) -Wstrict-prototypes -fPIC 4 CPPFLAGS = -g -Wall $(OPEN_O2) -fPIC 5 INCS = -I../include 6 SOURCES = $(wildcard *.c *.cpp) 7 OBJS = $(patsubst %.cpp,%.o, $(patsubst %.c, %.o, $(SOURCES))) 8 TARGETS = extract_str.a 9 SHARD_TARGETS = extract_str.so 10 11 .PHONY: all clean 12 13 .c.o: 14 $(CC) -c $(CFLAGS) -I. $(INCS) $< 15 .cpp.o: 16 $(CCC) -c $(CPPFLAGS) -I. $(INCS) $< 17 18 all: $(TARGETS) $(SHARD_TARGETS) 19 20 clean: 21 rm -f *.a *.o core core.* *~ 22 rm ../lib/$(TARGETS) 23 rm ../lib/$(SHARD_TARGETS) 24 25 $(TARGETS): $(OBJS) 26 ar -cr ../lib/$@ $^ 27 28 $(SHARD_TARGETS): $(OBJS) 29 $(CC) -shared -o ../lib/extract_str.so $^
源文件为C++,在生成动态库时使用的是gcc,导致C++标准库未被链接。两种修改方式
1. 用g++编译,命令改为:
1 $(CCC) -shared -o ../lib/extract_str.so $^
2. 继续使用gcc编译,添加链接参数 –lstdc++ 命令改为:
1 $(CC) -shared -o ../lib/extract_str.so $^ -lstdc++