关于C++/VS中DLL、#include与__declspec(dllimport)的基础疑问
关于C++/VS中DLL与#include的差异及DLL改造的问题解答
1. 编程结构角度:DLL与#include差异很大
#include是编译时代码嵌入:把被包含文件的代码直接插入到当前编译单元,最终所有代码会被链接到同一个可执行文件里,属于静态合并的结构。- DLL是运行时动态加载:代码被编译成独立的.dll文件,客户端程序在运行时才将DLL的代码映射到自身进程空间。这要求你必须把接口(函数/类声明)和实现分离——客户端只需要知道接口,不需要接触实现细节。
2. #include引用数量、结构差异明显
- 直接
#include的场景:客户端需要包含所有依赖的头文件,包括实现代码用到的内部结构体、辅助函数的头文件,因为编译时需要完整的代码定义才能生成可执行文件。 - DLL场景:客户端只需要包含导出接口的头文件,实现相关的头文件完全不需要暴露给客户端。比如DLL内部用到的工具类、私有结构体,客户端根本不用管,只要接口里没出现这些内容就行。
3. "将代码改为DLL仅需加__declspec(dllimport)并编译"的说法错误
实际要做的事情远不止这些:
- 区分导出和导入:DLL项目中用
__declspec(dllexport)标记要导出的函数/类,客户端用__declspec(dllimport),通常用宏统一管理,避免重复写:#ifdef MYDLL_EXPORTS #define MYDLL_API __declspec(dllexport) #else #define MYDLL_API __declspec(dllimport) #endif // 导出函数示例 MYDLL_API int Add(int a, int b); - 调整项目设置:在VS中要把项目类型改成动态链接库(.dll),编译后会生成.dll文件和对应的导入库(.lib)。
- 客户端链接:客户端项目需要链接DLL生成的.lib导入库,或者使用
LoadLibrary+GetProcAddress进行运行时动态加载。 - 处理C名字修饰:如果要让C或其他语言也能调用DLL函数,需要用
extern "C"包裹导出函数,避免C的名字 mangling(比如extern "C" MYDLL_API int Add(int a, int b);)。 - 依赖与部署:DLL运行时需要被客户端程序找到(比如放在同一目录或系统路径),如果DLL依赖其他库,也要确保这些依赖能被加载。
内容的提问来源于stack exchange,提问作者user3443063
相关产品推荐
相关产品推荐

