当我阅读gRPC中的代码时,我发现许多API使用GRPCAPI作为限定符。
GRPCAPI grpc_channel* grpc_cronet_secure_channel_create(
void* engine, const char* target, const grpc_channel_args* args,
void* reserved);当我单击指向GRPCAPI的链接时,它是一个空宏。
#ifndef GPRAPI
#define GPRAPI
#endif
#ifndef GRPCAPI
#define GRPCAPI GPRAPI
#endif我理解空宏的一些用法:
但在这里,GRPCAPI不属于任何一个。它仅仅是一个标记来告诉我们函数是一个API吗?还是对文档或其他功能有更大的影响?
发布于 2022-04-08 04:15:46
我非常感谢@Raildex的回答和@paulsm4的评论,它们非常鼓舞人心。
但是GRPCAPI和GPRAPI的确切功能被用来标记API为标签。
grpc中有一个名为api.py的脚本,它使用GPRAPI和GRPCAPI标签,这是唯一使用这两个标签的地方。
_RE_API = r'(?:GPRAPI|GRPCAPI|CENSUSAPI)([^;]*);'
for m in re.finditer(_RE_API, text): # match file content
...运行脚本后,我们将得到:
...
- arguments: void* engine, const char* target, const grpc_channel_args* args, void*
reserved
header: include/grpc/grpc_cronet.h
name: grpc_cronet_secure_channel_create
return_type: grpc_channel*
...发布于 2022-04-07 04:46:11
它要么用于特定于平台的属性,要么用于未来的属性。
对于Windows,通常可以指定
__declspec(dllexport)当编译库和
__declspec(dllimport)当使用库时。
宏是编译和使用宏的方便方法,因为您只在标头中定义宏的值为__declspec(dllexport)/__declspec(dllimport)。
其他编译器属性也是如此,例如GCC的__attribute__(visibility(default))/__attribute__(visibility(hidden))
现在,当库被静态链接时,您不需要所有这些,并且定义了没有值的宏。
一个例子是:
#ifdef STATIC_LIBRARY
#define LIBRARY_API
#else
#ifdef LIBRARY_EXPORTS
# define LIBRARY_API __declspec(dllexport)
#else
# define LIBRARY_API __declspec(dllimport)
#endif
LIBRARY_API void foo(); // when statically linked, it's a simple void function. If dynamically linked, it's either dllexport when compiling the library or dllimport when consuming it.另一种解释可以是调用约定修饰符。x86 (我只知道x86)有不同的调用约定--这些约定决定了调用方/被调用方如何在程序集级别上处理函数的参数。
就像这样:
#if WIN32
#define APICALL cdecl
#else
#define APICALL
#endif
APICALL void foo() // uses cdecl on WIN32https://stackoverflow.com/questions/71776309
复制相似问题