【问题标题】:Declare a C++ function that has C calling convention but internal linkage [duplicate]声明一个具有 C 调用约定但内部链接的 C++ 函数
【发布时间】:2020-01-28 12:42:13
【问题描述】:

我正在尝试与 C 库交互,它希望我提供指向回调函数的指针。

据我了解,根据标准,由于调用约定可能不同,回调必须具有 C 语言链接。我可以通过将我的回调函数声明为extern "C" 来实现这一点。然而,这有一个不受欢迎的副作用:将函数的未限定和未修改的名称暴露给其他翻译单元。

是否可以声明一个函数,使其名称具有内部链接(对其他翻译单元不可见),但可以通过指针从 C 调用(具有适当的调用约定)使用只有标准的 C++?

如果不可能使其具有内部链接,是否至少可以使其保持其 C++ 名称重整?

我试过了:

  • 将其声明为static extern "C" void f(); 导致编译错误,大意是staticextern "C" 不能一起使用。
  • 在匿名命名空间中将其声明为 namespace { extern "C" void f(); },结果证明与常规命名空间具有相同的效果,从而暴露了未损坏的未限定名称。

【问题讨论】:

  • 无需声明函数extern "C"。所需要的只是函数接受指向具有适当类型的参数和返回类型的函数的指针。接受指向函数的指针的函数不会从调用者那里获得有关传递函数名称的信息 - 被修改或其他方式。显然,类型必须在 C 中有效。我假设您没有使用任何编译器特定的关键字或调用约定。
  • 仅供参考:C/C++ Calling Conventions
  • @Peter 在answerlinked question 上的this comment 怎么样?这声称 C 和 C++ 函数之间的调用约定可能不同,因此在 extern "C" { } 中声明函数似乎更安全。
  • @KamilCuk 不保证适用于所有平台。这里有一些讨论:stackoverflow.com/questions/36941866/…

标签: c++ c extern linkage cross-language


【解决方案1】:
extern "C" {

static int my_callback(int a)
{
    return a + 1;
}

}

上面的代码编译得很好。该符号在翻译单元之外是不可见的,您可以通过指针调用该函数。

您可以在此文件中将此函数传递给您的 C 代码,并确保它不会污染您的全局命名空间。

【讨论】:

  • @yurikilochek 你能详细说明一下吗?
  • 我会过来引用cppreference language linkageWhen two functions with the same unqualified name are declared in different namespaces, and both have "C" language linkage, the declarations refer to the same function。从godbolt链接猜测,也许这就是令人困惑的OP。
  • 尝试从不同的翻译单元调用它。我自己尝试过,得到一个未定义的参考错误,这意味着这个解决方案有效。
  • 指所有情况。我不明白。那里的函数具有内部链接和 C 调用约定,证明这是可能的。
  • @yurikilochek 仍然无法从另一个文件访问您的 f 函数,因此您可以将它和引用它的 c++ 函数放在一个单独的文件中,然后就可以结束了。我认为这里是 gcc 根据标准做正确的事情。
猜你喜欢
  • 2018-12-06
  • 2021-06-16
  • 2012-12-14
  • 1970-01-01
  • 2021-05-16
  • 1970-01-01
  • 2013-09-10
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多