在grpc函数声明之前,空宏“ grpcapi”的效果是什么?

发布于 2025-01-19 11:34:27 字数 618 浏览 1 评论 0原文

当我在GRPC中读取代码时,我使用grpcapi作为预选赛发现了许多API。

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,这只是一个标记吗?或对文档或其他功能的效果更大?

When I read the code in gRPC, I found many APIs using GRPCAPI as qualifier.

GRPCAPI grpc_channel* grpc_cronet_secure_channel_create(
    void* engine, const char* target, const grpc_channel_args* args,
    void* reserved);

When I click the link to GRPCAPI, it's an empty macro.

#ifndef GPRAPI
#define GPRAPI
#endif

#ifndef GRPCAPI
#define GRPCAPI GPRAPI
#endif

I understand some usages of empty macro:

  • preventing multiple copies of the same header being included
  • used as a switch for debug or removing sensitive code

But here the GRPCAPI belongs to neither. Is it just a marker to tell us the function is an API? Or more effect for document or others functions?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

纵情客 2025-01-26 11:34:27

它要么用于特定于平台的属性,要么用于未来的属性。

对于 Windows DLL,您通常指定
__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 WIN32

Its either for platform specific attributes or for future attributes.

For Windows DLLs, you usually specify
__declspec(dllexport) when compiling the library and
__declspec(dllimport) when consuming the library.

A macro is the convenient way to both compile and consume it because you only define the value of the macro to be __declspec(dllexport)/__declspec(dllimport) within the header.
the same goes for other compiler attributes, such as __attribute__(visibility(default))/__attribute__(visibility(hidden)) on GCC

Now when the library is statically linked, you don't need all that and you define the macro to have no value.
An example would be:

#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.

Another explanation can be a calling convention modifier.
x86 (I only know x86) has different calling conventions - these decide how the caller/callee treats parameters of functions on the assembly level.

Something like this:

#if WIN32
#define APICALL cdecl
#else
#define APICALL 
#endif

APICALL void foo() // uses cdecl on WIN32

风铃鹿 2025-01-26 11:34:27

我非常感谢@RailDex的答案以及 @paulsm4的评论,这是非常鼓舞人心的。

但是grpcapigprapi的确切功能用于将API标记为标签。

GRPC中有一个名为使用标签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*
...

I really appreciate the answer from @Raildex and comment from @paulsm4, which are very inspiring.

But the exactly function of GRPCAPI and GPRAPI is used to mark APIs as a label.

There is a script in grpc named list_api.py using the label GPRAPI and GRPCAPI, which is the only place using these two labels.

_RE_API = r'(?:GPRAPI|GRPCAPI|CENSUSAPI)([^;]*);'

for m in re.finditer(_RE_API, text):   # match file content
...

After running the script, we'll get:

...
- 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*
...
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文