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

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

4

1 回答 1

4

像这样的宏主要是为了与不同的 C 编译器兼容而添加的。您会在 1980 年代和 1990 年代的代码中发现这一点,这些编译器要么兼容 K&R(早于 ANSI C),要么缺乏各种特性。

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

链接约定

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

一致的字体大小

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

原型支持

80 年代的许多编译器都是按照 C 的 K&R 标准构建的,不支持 ANSI 函数原型。ML_FUNCML_ARGS_LIST宏解决了这个问题 。

如果支持原型,ML_ARGS_LIST则将定义并ML_FUNC(x)扩展为x. 完全扩展,忽略ML_EXTERNand_ML_AB将是:

M_Process(ML_INT i)

如果编译器不支持原型,ML_FUNC(x)则将展开为x()并省略原型参数列表。完整的扩展将是:

M_Process()

在 K&R C 中,所有参数都根据规则强制执行,参数变量在定义函数的地方定义,而不是声明。有关C 版本差异的一些详细信息,请参阅Wikipedia 关于 C 的条目。

于 2013-07-10T19:04:59.730 回答