使用cl.exe编译生成的库函数无法被外部访问如何解决
问题描述
使用微软cl.exe编译器将add函数编译为库文件时,编译产出的所有函数均无法被外部访问。已参考相关方案在头文件中添加extern "C"声明,对应代码如下:
#ifdef __cplusplus #define EXTERNC extern "C" #else #define EXTERNC #endif EXTERNC int add(int a, int b);
使用的编译命令为:
cl /LD add.c
编译生成的二进制文件经Dependency Walker检测,未查询到可被外部访问的add函数导出符号。
故障原因
仅添加extern "C"声明无法让cl.exe自动将函数标记为导出符号:
extern "C"仅负责处理名称修饰问题:它的作用是告诉C编译器不要对函数名做C规则的名称改编,适配C语言的链接规则。你当前编译的是.c后缀文件,cl默认按C语法编译,本身就不会做C++名称修饰,这部分声明在当前编译场景下不解决导出问题- cl编译动态库默认不导出普通函数:编译动态库时,cl.exe默认不会将普通函数加入dll导出表,必须显式标记需要导出的函数,否则外部程序无法定位到对应函数地址
修复方案
两种方案二选一即可:
方案1:源码中添加导出标记
修改头文件,增加动态库导出/导入宏定义,给需要对外暴露的函数加上__declspec(dllexport)编译期标记:
#ifdef __cplusplus #define EXTERNC extern "C" #else #define EXTERNC #endif #ifdef BUILD_ADD_LIB #define ADD_API EXTERNC __declspec(dllexport) #else #define ADD_API EXTERNC __declspec(dllimport) #endif ADD_API int add(int a, int b);
编译时追加宏定义参数,命令如下:
cl /LD add.c /DBUILD_ADD_LIB
编译后add函数会被自动加入导出表。
方案2:使用def模块定义文件导出
无需修改原有代码,在源码同级目录新建add.def文件,写入以下内容:
LIBRARY add EXPORTS add @1
编译时指定def文件即可,命令如下:
cl /LD add.c add.def
补充:如果后续你将源码后缀改为.cpp按C模式编译,当前写的
extern "C"相关逻辑就会生效,可以避免C名称修饰导致的链接找不到函数问题。
内容的提问来源于stack exchange,提问作者Shrimp33
相关产品推荐
相关产品推荐

