C头文件宏

时间:2013-07-10 18:40:03

标签: c

ML_EXTERN _ML_AB ML_FUNC(M_Process)
#ifdef ML_ARGS_LIST
(
  ML_INT i
);
#endif

如果我为供应商(需要实现这些接口)创建接口,为什么我的API中会有上述声明?我认为它被称为宏 - 为什么我不会像“普通”那样声明函数:int M_Process();?有什么区别,以上声明的各个部分有什么作用?

1 个答案:

答案 0 :(得分:4)

这些宏很大程度上是为了与不同的C编译器兼容而添加的。您可以在20世纪80年代和90年代的代码中找到符合K& R标准(早于ANSI C)或缺少各种功能的编译器。

你必须阅读宏定义才能绝对肯定,但这种事情有一些常见的模式。宏分为几种类型:

链接约定

通过定义ML_EXTERN,API可以支持不同的calling conventions(例如,stdcall,fastcall等)或不同类型的外部链接(例如,Microsoft的dllexport)。这提供了编译器兼容性和跨平台兼容性,同时不会显着影响代码可读性。

一致的类型大小

intshortlong等类型的位数取决于平台,但存在一些限制。许多早于标准inttypes.hstdint.h标头的库都使用宏或typedef来确保它们的类型在所有平台上都具有相同的大小。 ML_INT是适当大小的整数类型的宏或typedef。

原型支持

80年代的许多编译器都是根据C的K& R标准构建的,不支持ANSI函数原型。 ML_FUNCML_ARGS_LIST宏对此进行了解决。

如果支持原型,则会定义ML_ARGS_LISTML_FUNC(x)会扩展为x。完全展开,忽略ML_EXTERN_ML_AB将是:

M_Process(ML_INT i)

如果编译器不支持原型,那么ML_FUNC(x)将扩展为x(),并且将省略原型参数列表。完全扩展将是:

M_Process()

在K& R C中,根据规则强制所有参数,并且定义参数变量,而不是声明函数。有关C版本差异的一些详细信息,请参阅Wikipedia's entry on C