C++调用C函数链接失败主因是name mangling,需用extern "C"包裹C头文件声明;参数须为C兼容类型;链接时注意库顺序、架构匹配及运行时依赖。
因为C++编译器默认对函数名做name mangling(名称修饰),比如把 void init() 编译成类似 _Z4initv 的符号;而C编译器生成的是未修饰的 init。链接器找不到匹配符号,报 undefined reference to 'init'。
必须作用于函数声明(不是定义),且需在C++代码中包裹C头文件或函数声明。常见错误是只加在实现文件里,或漏掉条件宏。
#ifdef __cplusplus 包裹extern "C" —— 那会让C编译器报错extern "C" 宏(如 LIBRARY_API_BEGIN),优先用它的#ifdef __cplusplus
extern "C" {
#endif
#include "c_library.h" // 确保这个头里全是C风格声明
#ifdef __cplusplus
}
#endif
C++调用C函数时,参数和返回值必须是C兼容类型。C++特有类型(如 std::string、class、重载函数)不能直接传入C函数。
const char*,别传 std::string 对象,要用 s.c_str()
str
uct config { int a; }; ,C++中可直接用,但别在里面加构造函数或虚函数extern "C" 链接属性,否则C库调用会崩溃extern "C" {
void my_callback(int code) {
// 这个函数可被C库安全调用
}
}
// 注册时:
c_library_set_callback(my_callback); // 正确
// c_library_set_callback([](int){}); // 错误:lambda不是C链接函数
即使声明加了 extern "C",链接阶段仍可能失败,原因常不在C++侧。
-lc)在后,例如 g++ main.o -L. -lc_library
nm -C libxxx.a | grep init 可查符号是否存在)__declspec(dllimport),且C++调用时需对应最易忽略的是:C库内部调用了另一个C++运行时(比如它偷偷 new 了对象),而你的工程没链接 libstdc++ 或 libc++ —— 这会导致运行时崩溃,而非链接时报错。