You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

无法将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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 03:50:10