1. .h 文件(头文件,Header File)
核心作用:相当于程序的 “接口说明书”。它不包含函数 / 变量的具体实现代码,只声明函数名、参数、返回值、宏定义、结构体 / 类的定义等。
2. .lib 文件(库文件,Library File)
核心作用:分为两种类型,是链接器(Linker)用来链接程序的 “桥梁”:
-
静态库(静态.lib):包含函数 / 变量的完整实现代码,编译时会被完整复制到最终的可执行文件(.exe)中。
-
导入库(动态.lib):仅包含.dll 文件的 “入口信息”(如函数在.dll 中的位置),编译时只告诉程序 “去哪里找.dll 里的功能”,不会复制代码到.exe。
3. .dll 文件(动态链接库,Dynamic Link Library)
核心作用:包含函数 / 变量的具体实现代码,但不会被打包到.exe 中,而是在程序运行时被加载和调用。多个程序可以共享同一个.dll,节省内存和磁盘空间。
4. .h 文件C/C++ 混合编程
#ifdef
__cplusplus extern "C" {
#endif
4.1 C 和 C++ 的编译差异
C++ 支持函数重载(比如add(int)和add(int, int)可以共存),而 C 语言不支持。为了实现重载,C++ 编译器会对函数名进行名字改编(也叫名字修饰):
-
C 编译器编译
int add(int a, int b)时,函数名保持为add; -
C++ 编译器编译同一个函数时,会把函数名改成类似
?add@@YAHHH@Z的形式(包含参数类型信息),以此区分不同重载版本。
问题就出在这里:如果你的 DLL 是用 C++ 编写的,但想让 C 语言程序(或其他按 C 规则调用的语言)调用,C 编译器不认识 C++ 改编后的名字,会导致 “找不到函数” 的链接错误。
4.2 #ifdef __cplusplus extern "C" { #endif 的核心意义
这段代码的作用是:让 C++ 编译器按 C 语言的规则编译花括号内的代码(不进行名字改编),同时保证代码在 C 编译器下也能正常编译。
拆解每一部分:
-
#ifdef __cplusplus:__cplusplus是 C++ 编译器特有的宏,只有用 C++ 编译器编译时,这个条件才成立;C 编译器会忽略这段代码。 -
extern "C":告诉 C++ 编译器,后续代码按 C 语言的编译规则处理(核心是禁用名字改编)。 -
{ ... }:包裹需要按 C 规则编译的代码(通常是函数声明 / 导出函数)。 -
#endif:结束条件编译。
// demo.h 完成代码
#ifdef __cplusplus
extern "C" { // C++编译器进入这个分支,按C规则编译
#endif
__declspec(dllexport) int add(int a, int b);
#ifdef __cplusplus
} // 闭合extern "C"
#endif
4.3 总结
extern "C"仅对函数名 / 函数声明有效,不能用于 C++ 特有的语法(比如类、模板),因为 C 语言不支持这些特性;- 一旦用
extern "C"修饰函数,该函数不能重载(因为 C 语言不支持重载,强行重载会编译报错); - 这段代码主要用在需要跨 C/C++ 调用的场景(比如 DLL 导出函数、静态库接口),纯 C++ 项目内部代码不需要加。
__cplusplus是 C++ 编译器的专属宏,用于区分 C/C++ 编译环境;extern "C"强制 C++ 编译器按 C 语言规则编译代码,核心是禁用名字改编;- 整段代码的作用是让接口同时兼容 C 和 C++ 编译器,解决跨语言调用的链接问题。
1224

被折叠的 条评论
为什么被折叠?



