当前位置:   article > 正文

c语言 extern_extern、#define、#ifdef __cplusplus

#define externc_begin extern "c" {

一 、externextern "C"

参考:

深入理解extern用法_奔跑的小河-CSDN博客_extern用法​blog.csdn.net

extern做变量声明: 声明extern关键字的全局变量和函数可以使得它们能够跨文件被访问。

注意: 全局函数的声明语句中,关键字extern可以省略,因为全局函数默认是extern类型的。

extern 

如果在一个文件里定义了char g_str[] = "123456";在另外一个文件中必须使用extern char g_str[ ];来声明。不能使用extern char* g_str;来声明。extern是严格的声明。且extern char* g_str只是声明的一个全局字符指针。

注:声明可以拷贝n次,但是定义只能定义一次。

通常,在模块的头文件中对本模块提供给其它模块引用的函数和全局变量以关键字extern声明。例如,如果模块B欲引用该模块A中定义的全局变量和函数时只需包含模块A的头文件即可。这样,模块B中调用模块A中的函数时,在编译阶段,模块B虽然找不到该函数,但是并不会报错;它会在链接阶段中从模块A编译生成的目标代码中找到此函数。

extern 和 static 的区别:与extern对应的关键字是static,被它修饰的全局变量和函数只能在本模块中使用。因此,一个函数或变量只可能被本模块使用时,其不可能被extern “C”修饰。

extern "C" 包含双重含义,从字面上即可得到:首先,被它修饰的目标是“extern”的;其次,被它修饰的目标是“C”的。 extern "C"用来实现C++与C的混合编程。

extern "C"的惯用法:在C++中引用C语言中的函数和变量,在包含C语言头文件(假设为cExample.h)时,需进行下列处理:

extern 

二、#define

参考:

c/c++中define用法详解及代码示例_不很正派的专栏-CSDN博客_c++ define​blog.csdn.net
bfc38f588a5a563ccc7eed2a39adf903.png

1.无参宏定义

#define 标识符 字符串

其中的“#”表示这是一条预处理命令。凡是以“#”开头的均为预处理命令。“define”为宏定义命令。“标识符”为所定义的宏名。“字符串”可以是常数、表达式、格式串等。例如:

#define MAXNUM 99999

2. 有参宏定义

#define 宏名(形参表) 字符串

C++语言允许宏带有参数。在宏定义中的参数称为形式参数,在宏调用中的参数称为实际参数。对带参数的宏,在调用中,不仅要宏展开,而且要用实参去代换形参。例如:

#define add(x, y) (x + y)

三、空宏 + 函数名:XXX void function()

参考:

C/C++:函数名前引用一个空的宏定义_白马青衫等风来的博客-CSDN博客​blog.csdn.net
46bbb9bd352310cefac1d21b490937a3.png

如下,定义了空宏CLASS_DEF,函数声明前带上了空宏,这样做一般是为了

1)编译指示;为了以后其它平台有需要添加的或扩展的编译时选项而预留的。

2)方便阅读;对函数进行标识,说明。

#define CLASS_DEF     

四、#ifdef __cplusplus

参考:

关于“#ifdef __cplusplus” 和 " extern "C" 的问题​blog.csdn.net
ed0d291d60041da103b5065f028625c2.png

c++代码中经常会出现如下代码:

#ifdef __cplusplus 

__cplusplus 是cpp中的自定义宏,那么定义了这个宏的话表示这是一段cpp的代码,也就是说,上面的代码的含义是:如果这是一段cpp的代码,那么加入extern "C"{}处理其中的代码。

在c++中,为了支持重载机制,在编译生成的汇编码中,要对函数的名字进行一些处理,加入比如函数的返回类型等等.而在C中,只是简单的函数名字而已,不会加入其他的信息.也就是说:C++和C对产生的函数名字的处理是不一样的.

试想这样的情况:一个库文件已经用C写好了而且运行得很良好,这个时候我们需要使用这个库文件,但是我们需要使用C++来写这个新的代码。如果这个代码使用的是C++的方式链接这个C库文件的话,那么就会出现链接错误。因此,为了在C++代码中调用用C写成的库文件,就需要用extern "C"来告诉编译器:这是一个用C写成的库文件,请用C的方式来链接它们。

五、typedef void (*funcptr)(void)

参考:https://blog.csdn.net/liangtianmeng/article/details/84092446

typedef 

这里是定义了一个指向参数为空,返回值为空的函数的指针类型。

typedef 只对已有的类型进行别名定义,不产生新的类型;

#define 只是在预处理过程对代码进行简单的替换。

六、C语言API接口常用写法

参考:

C語言API接口文档​www.jianshu.com
47600f0092763ab87beda851549a939a.png

API接口文档一般遵循这些规范:
1)编程风格:编程风格一致,此外,編程命名函数和变量时,用英文表述它的具体含义。
2)原子独立:API接口必须是定义明确,功能独立的;如果一个函数能通过其他函数组合实现,你就不要提供这个函数,让用户自己去实现。
3)接口清楚:接口包括exported 函数及抽象数据类型
4)函数:必须显示地让调用者明白接口使用方法及约束:输入参数,输出参数,错误处理,线程是否安全,是否support c++等。
5)抽象数据类型:一个抽象数据类型是一个接口,它定义了一个数据类型和对该类型的值所进行的操作。高级类型是抽象的,因为其接口隐藏了相关的表示细节,并只规定了对该类型值的合法操作。理想情况下,这些操作不会暴露类型的表示细节,因为那样可能使应用程序隐含地依赖于具体的表示。
6)错误处理机制:错误处理返回码应清晰具体,这样便于排查问题。
7)接口封闭:必须有头有尾,比如你提供了void *context_create();,内部实现malloc一块内存,那么对应的你需要有相应接口释放这块内存空间,比如void context_destroy(void *ctx)。
8)可移植性:头文件要做到可移植性,至少看起来你的实现支持windows和linux平台。通过宏来实现。
9)测试:需要有单元测试,功能测试,稳定性测试及性能测试结果。

头文件示例代码:

// example.h
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家小花儿/article/detail/264353
推荐阅读
相关标签
  

闽ICP备14008679号