C++构建与调用DLL疑问:仅用dllexport为何无需dllimport?
问题解答
这是完全正常的现象,原因可以从以下几点拆解:
1. __declspec(dllexport) 和 __declspec(dllimport) 的核心作用
__declspec(dllexport):在DLL项目中标记需要对外暴露的函数/类,编译时会把这些符号写入导出表,同时生成对应的导入库(.lib文件)。__declspec(dllimport):是给客户端项目用的优化提示,告诉编译器「这个符号来自外部DLL」,编译器会生成更高效的间接调用代码,避免额外的跳转桩。但它不是强制要求的——没有它,编译器会默认把符号当作外部未定义符号,交给链接器处理。
2. 客户端不用dllimport也能运行的本质
只要你的客户端项目在链接阶段正确引入了DLL对应的.lib导入库,链接器就会从.lib里找到DLL中导出函数的地址信息,把客户端代码里的函数调用和DLL的实际函数关联起来。哪怕没有dllimport声明,链接器依然能完成这个绑定,所以程序能正常运行。
3. 微软教程用宏切换的原因
教程里的MATHLIBRARY_EXPORTS宏是为了让同一个头文件能同时给DLL项目和客户端项目使用:
- 在DLL项目中,这个宏会被添加到项目的预处理器定义里(Visual Studio路径:项目属性 → C/C++ → 预处理器 → 预处理器定义),此时头文件会把
MATHLIBRARY_API解析为__declspec(dllexport)。 - 在客户端项目中,不定义这个宏,头文件就会把
MATHLIBRARY_API解析为__declspec(dllimport),自动启用调用优化。
4. 不用dllimport的小影响
虽然功能正常,但没有dllimport时,编译器会生成一个额外的跳转函数(桩函数)来间接调用DLL中的函数,相比用dllimport的直接调用,会有极其微小的性能损耗——对于大多数场景来说,这个损耗可以忽略不计,但规范的做法还是建议按教程用宏切换,保证代码的可维护性和最优性能。
内容的提问来源于stack exchange,提问作者lewjj
相关产品推荐
相关产品推荐

