【问题标题】:Preprocessor macro definitions used with C function definition与 C 函数定义一起使用的预处理器宏定义
【发布时间】:2015-09-25 03:05:36
【问题描述】:

我正在研究SQLite源代码(在c中),但是有些东西我无法弄清楚它们是什么,希望您能帮帮我。 我知道 c、c++ 和 JAVA 基础知识,但我从未见过这样的东西,也不知道如何搜索它。

在 c 文件中,有以下定义(等等):

#ifndef SQLITE_CDECL
# define SQLITE_CDECL
#endif
#ifndef SQLITE_API
# define SQLITE_API
#endif

然后上面的定义是这样使用的:

SQLITE_API int SQLITE_CDECL sqlite3_conf(int, ...){
  //code

我知道“SQLITE_API”和“SQLITE_CDECL”不是返回类型、函数名、关键字、K&R 风格也不是变量修饰符...

为什么这些词在函数中是这样放置的?它们是干什么用的?

【问题讨论】:

  • 在这个例子中很难看到,因为 SQLITE_CDECL 和 SQLITE_API 似乎都“什么都不做”。在某些平台上,可能需要“cdecl”来指定调用顺序。在其他平台上,可能需要“__declspec(dllimport)”来指定“.dll”与“.exe”。这是一个示例,其中 Sqlite 构建可能被配置为同时提供 SQLITE_CDECL 和 SQLITE_API 有意义的非空值:__declspec(dllimport) void _cdecl func1(void);

标签: c sqlite function c-preprocessor


【解决方案1】:

它们用于在不同平台或构建某些方式时修改函数的属性。大多数时候可能不需要它们,但在某些情况下它们可能很有用,例如在构建 DLL 时使用__declspec(dllexport),或者在直接包含文件时使用static,而不是让链接器在目标文件之间执行链接。

【讨论】:

  • 那么,如果我的回答正确,这些词可以替换为“静态”或空格(例如)?
  • 是的,完全正确。有关其他非 Microsoft 示例,另请参阅 Gnu function attributes
【解决方案2】:

这两个声明看起来像是存在的,因此可以对它们进行不同的定义,以支持 Windows 上的某些开发怪癖。请注意,在 #define 行上,它们没有定义为任何值。这意味着它们将被解析器看到的任何内容替换。因此,SQLITE_API int SQLITE_CDECL sqlite3_conf(int, ...){ 在预处理器运行后最终会减少为int sqlite3_conf(int, ...){。在 Windows 上,可以对它们进行不同的定义,以支持使用 __declspec(参见 https://msdn.microsoft.com/en-us/library/dabb5z75.aspx)构建 DLL 并指定调用约定(参见 https://msdn.microsoft.com/en-us/library/zkwh89ks.aspx)。

【讨论】:

    猜你喜欢
    • 2011-01-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2010-10-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多