无法将C共享对象链接至C++11程序的Makefile问题
解决C++11程序链接C99共享库的问题
你遇到的是C/C++混合编程里典型的名字修饰不兼容+链接顺序错误问题,下面分步骤帮你搞定:
1. 修复C++代码的C函数声明
C++编译器会对函数名做「名字修饰」(比如给binarion_constructor附加类型信息),但你的C99库是用C编译器编译的,函数名没有被修饰,导致链接器找不到匹配的符号。
解决方法很简单:在C++代码(比如tests/testing.cpp或对应头文件)里,用extern "C"包裹所有来自C库的函数声明:
extern "C" { // 把你要调用的C库函数声明都放这里,比如: void binarion_constructor(unsigned int some_param); // 其他C库函数也一并添加 }
如果有对应的C头文件(比如hanoi.h),更规范的做法是给头文件加条件编译,让它同时兼容C和C++:
#ifdef __cplusplus extern "C" { #endif // 原来的C函数声明 void binarion_constructor(unsigned int some_param); #ifdef __cplusplus } #endif
这样不管是C还是C++代码包含这个头文件,都能正确处理函数名。
2. 调整Makefile的链接顺序
GCC/G++的链接器是从左到右处理输入文件的,库文件必须放在依赖它的源文件/目标文件后面——不然链接器先处理库时,还没看到需要这些符号的代码,就会直接忽略库的符号。
把你的编译命令改成这样:
main: tests/testing.cpp tests/main.cpp g++ -std=gnu++11 -L. -o main tests/testing.cpp tests/main.cpp -lhanoi
核心是把-lhanoi移到所有源文件的后面。
额外的Makefile优化建议
为了让Makefile更清晰好维护,可以拆分编译和链接步骤,同时加上共享库的依赖:
# 编译器与编译选项 CXX = g++ CXXFLAGS = -std=gnu++11 -Wall -Wextra LDFLAGS = -L. LDLIBS = -lhanoi # 目标文件列表 OBJS = tests/testing.o tests/main.o # 最终可执行文件目标 main: $(OBJS) libhanoi.so $(CXX) $(LDFLAGS) -o $@ $(OBJS) $(LDLIBS) # 编译C++源文件为目标文件 tests/%.o: tests/%.cpp $(CXX) $(CXXFLAGS) -c -o $@ $< # 保持你原来的libhanoi.so编译规则 libhanoi.so: [你的C源文件列表] gcc -std=c99 -fPIC -shared -o $@ [你的C源文件列表]
先试试调整链接顺序,再确认extern "C"的声明是否正确,应该就能顺利完成链接了。
内容的提问来源于stack exchange,提问作者firstname gklsodascb
相关产品推荐
相关产品推荐

