#ifdef __cplusplus extern "C" 笔记

本文深入探讨了C++中使用DLL导入机制的过程,包括如何在C++代码中导入DLL中的函数,以及如何在DLL定义公共符号时使用__declspec(dllimport)关键字。文章详细解释了DLL导入的概念,提供了实例代码演示,并强调了使用该关键字的重要性。
#ifdef __cplusplus //c++编译环境中才会定义__cplusplus (plus就是"+"的意思)
extern "C" { //告诉编译器下面的函数是c语言函数(因为c++和c语言对函数的编译转换不一样,主要是c++中存在重载)

#endif


C++编译器编译时生成函数名称的规则和C编译器不一样,如果是在C++中使用用C语言编译器编译生成的库文件,就需要用这个,防止C++编译器链接不到函数。

以下来自MSDN:


使用 __declspec(dllimport) 导入到应用程序中

如果一个程序使用 DLL 定义的公共符号,就说该程序是在导入公共符号。 为使用 DLL 生成的应用程序创建头文件时,在公共符号的声明上使用 __declspec(dllimport) 不论是用 .def 文件导出还是用__declspec(dllexport) 关键字导出,__declspec(dllimport) 关键字均有效。

若要提高代码的可读性,请为 __declspec(dllimport) 定义一个宏,然后使用此宏声明每个导入的符号:

#define DllImport   __declspec( dllimport )

DllImport int  j;
DllImport void func();

在函数声明上使用 __declspec(dllimport) 是可选操作,但如果使用此关键字,编译器将生成更有效的代码。 但是,为使导入的可执行文件能够访问 DLL 的公共数据符号和对象,必须使用 __declspec(dllimport) 请注意,DLL 的用户仍然需要与导入库链接。

对 DLL 和客户端应用程序可以使用相同的头文件。 为此,请使用特殊的预处理器符号来指示是生成 DLL 还是生成客户端应用程序。 例如:

#ifdef _EXPORTING
   #define CLASS_DECLSPEC    __declspec(dllexport)
#else
   #define CLASS_DECLSPEC    __declspec(dllimport)
#endif

class CLASS_DECLSPEC CExampleA : public CObject
{ ... class definition ... };
了解更多可以在MSDN上搜索dllimport dllexport关键字。

### 正确命名头文件保护符的宏以避免冲突 在C或C++编程中,使用头文件保护符时,正确命名宏可以有效避免冲突。通常的做法是基于头文件名生成唯一的宏标识符,并采用大写字母和下划线分隔单词的形式[^1]。 例如,如果头文件名为 `example.h`,可以将其转换为宏名称 `EXAMPLE_H`。为了进一步增强唯一性,可以在宏名称前添加项目或模块的前缀。例如,对于项目 `MyProject` 和头文件 `utils.h`,宏名称可以定义为 `MYPROJECT_UTILS_H`[^2]。 ```c #ifndef MYPROJECT_UTILS_H #define MYPROJECT_UTILS_H // 头文件内容 #endif // MYPROJECT_UTILS_H ``` 这种命名方式不仅简单直观,而且通过添加项目前缀,能够显著降低与其他项目头文件发生命名冲突的风险。 ### `#ifdef __cplusplus` 的作用 `#ifdef __cplusplus` 是一种条件编译指令,用于检测当前代码是否正在被C++编译器编译。C++编译器会定义 `_cplusplus` 宏,而C编译器不会。因此,这一指令常用于区分C和C++代码的处理方式[^3]。 典型的应用场景是在C++中包含C语言编写的头文件时。由于C++对函数重载的支持,直接包含C语言头文件可能导致符号冲突。通过 `#ifdef __cplusplus`,可以在C++环境中将C语言函数声明封装在 `extern "C"` 中,从而避免符号冲突问题[^4]。 ```c #ifdef __cplusplus extern "C" { #endif void c_function(); #ifdef __cplusplus } #endif ``` 上述代码片段中,当代码由C++编译器编译时,`extern "C"` 告诉编译器以C语言的方式处理函数声明,防止C++编译器对其进行名称修饰[^5]。 ### `extern "C"` 的用法 `extern "C"` 是C++中的一个关键字,用于指定函数或变量使用C语言的链接方式。在C++中,函数名会被进行名称修饰(name mangling),以便支持函数重载等功能。然而,这种修饰会导致C++编译器无法正确调用未修饰的C语言函数。通过 `extern "C"`,可以确保函数以C语言的方式链接,从而兼容C语言代码[^6]。 以下是一个完整的示例,展示如何在C++中包含C语言头文件并正确调用C语言函数: ```c // 文件:my_c_header.h #ifndef MY_C_HEADER_H #define MY_C_HEADER_H #ifdef __cplusplus extern "C" { #endif void my_c_function(); #ifdef __cplusplus } #endif #endif // MY_C_HEADER_H ``` 在上述代码中,`extern "C"` 确保 `my_c_function` 在C++环境中以C语言的方式链接,从而避免名称修饰带来的问题。 ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值