ML_EXTERN _ML_AB ML_FUNC(M_Process)
#ifdef ML_ARGS_LIST
(
ML_INT i
);
#endif
如果我为供应商(需要实现这些接口)创建接口,为什么我的API中会有上述声明?我认为它被称为宏 - 为什么我不会像“普通”那样声明函数:int M_Process();
?有什么区别,以上声明的各个部分有什么作用?
答案 0 :(得分:4)
这些宏很大程度上是为了与不同的C编译器兼容而添加的。您可以在20世纪80年代和90年代的代码中找到符合K& R标准(早于ANSI C)或缺少各种功能的编译器。
你必须阅读宏定义才能绝对肯定,但这种事情有一些常见的模式。宏分为几种类型:
通过定义ML_EXTERN
,API可以支持不同的calling conventions(例如,stdcall,fastcall等)或不同类型的外部链接(例如,Microsoft的dllexport
)。这提供了编译器兼容性和跨平台兼容性,同时不会显着影响代码可读性。
int
,short
和long
等类型的位数取决于平台,但存在一些限制。许多早于标准inttypes.h
和stdint.h
标头的库都使用宏或typedef来确保它们的类型在所有平台上都具有相同的大小。 ML_INT
是适当大小的整数类型的宏或typedef。
80年代的许多编译器都是根据C的K& R标准构建的,不支持ANSI函数原型。 ML_FUNC
和ML_ARGS_LIST
宏对此进行了解决。
如果支持原型,则会定义ML_ARGS_LIST
,ML_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。