我正在查看PnP Configuration Manager functions并看到每个都以这三个宏开头:
CMAPI CONFIGRET WINAPI
我必须在 CfgMgr32.h 中挖掘才能找到CMAPI
,其定义为:
#if !defined (_CFGMGR32_)
#define CMAPI DECLSPEC_IMPORT
#else
#define CMAPI
#endif
根据Tim Roberts' article on DLL's in Kernel Mode,这允许CMAPI
的函数在运行时或链接时加载。我们已经知道WINAPI
只是macro for a calling convention。
但是CONFIGRET
呢?从 CfgMgr32.h ,它被定义为:
//
// Standardized Return Value data type
//
typedef _Return_type_success_(return == 0) DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
我之前从未见过这个,这是什么意思?这些函数的返回类型是什么?
答案 0 :(得分:2)
CONFIGRET
的基础数据类型为DWORD
,如 CfgMgr32.h 中所定义:
//
// Standardized Return Value data type
//
typedef _Return_type_success_(return == 0) DWORD RETURN_TYPE;
typedef RETURN_TYPE CONFIGRET;
CONFIGRET
是RETURN_TYPE
的别名,RETURN_TYPE
是DWORD
的别名,其附加的语义信息通过SAL annotations附加(SAL注释为由静态代码分析器使用。)
Annotating Function Behavior包含有关此特定注释的详细信息:
_Return_type_success_(expr)
可以应用于typedef。指示返回该类型且未明确包含 _Success _ 的所有函数都注释为具有
_Success_(expr)
。 _Return_type_success _ 不能用于函数或函数指针typedef。
<小时/> CfgMgr32.h 中定义的
CMAPI
预处理程序符号为
#if !defined (_CFGMGR32_)
#define CMAPI DECLSPEC_IMPORT
#else
#define CMAPI
#endif
与您提出的目的不同:它允许相同的头文件用于库的使用者和生产者。生产者定义_CFGMGR32_
预处理器符号,并提供函数定义。消费者没有定义_CFGMGR32_
预处理器符号,CMAPI
扩展为导入说明符(__declspec(dllimport)
,在 ntdef.h 中定义。这用于Load-Time Dynamic Linking(与Run-Time Dynamic Linking)。它根本不用于静态链接。