【问题标题】:Is there any way to declare function as extern "C" with g++ flag?有没有办法用 g++ 标志将函数声明为 extern "C"?
【发布时间】:2013-11-25 18:33:28
【问题描述】:

我指的是this线程,我有同样的要求(包装函数调用),需要extern“C”声明。

在我的例子中,这个原型是在一个单独的头文件下声明的,我不想更改这个头文件或原始代码文件(在其中进行函数调用)。 但我仍然希望编译器将我的函数视为 extern "C"。 所以,我想知道是否有办法用 g++ 标志提供这些信息(例如“--externc=foobar”之类的东西)。

【问题讨论】:

  • 如果您真的在问题中给出了您要修改的实际函数的声明代码,这将对我们有所帮助。

标签: c++ c gcc g++


【解决方案1】:

当包含 C 头文件时,如果它们没有相应的包装器 [有条件地在 __cplusplus] 内部,您通常需要用 extern "C" 块包装它们:

extern "C" {
#include <c-header.h>
}

嵌套这些块是无害的,只是它可以防止将标头迁移到 C++,即内部 extern "C"-block 是可取的。如果标头是 C++ 标头,则需要跳过转发函数:

extern "C" void call_as_c() {
    actual_cxx_function();
}

仅仅假装符号的链接与实际不同是行不通的。

【讨论】:

  • 但如果标头是真正的 C++,这可能不起作用,例如如果它包含同名但不同签名的重载函数。
  • 我认为第二种解决方案(内联函数)应该可以工作。但由于 OP 确实想要更改调用站点,因此您还需要一个宏来将源中的 actual_function 调用转换为 call_as_c(具有讽刺意味的是,它随后调用了 actual_function)。
  • @BasileStarynkevitch:正确。因此,如果标题恰好是底部的 C++ 标题,如果我的回答是关于该怎么做的评论。
  • @Damon:好吧,我错过了。嗯,我想要很多我不能拥有的东西。除非这些愿望有技术原因,否则我认为正确的解决方案是处理它。任何可以使用的宏黑客都像重命名符号一样脆弱。
【解决方案2】:

如果您想更改链接/调用约定(这是extern "C" 完全有权做的事情),几乎唯一安全的答案是在声明函数的位置更改它 - 即:在标题中。否则,您可能会冒着定义与使用不同的函数的风险,并且随之而来的是欢闹。

【讨论】:

    【解决方案3】:

    我相信这不是一件容易的事(在之前的标头中声明一个函数为extern "C" 后声明)。

    如果您只有一个这样的函数(而且数量不多),我认为最简单的解决方案是更改标头,或者在包含标头之前声明该函数extern "C"(如果签名和参数或该函数的结果类型允许它,例如,如果相关类型在其他标头中定义,等等...)。

    或者,编写一些(例如在sedawk 中)脚本来转换标题。

    您还可以考虑使用例如自定义 GCC以MELT 编码的扩展(一种扩展 GCC 的特定领域语言),它会根据需要更改声明的内部表示。我不确定你的情况是否值得。

    【讨论】:

      猜你喜欢
      • 2018-02-12
      • 2020-05-25
      • 1970-01-01
      • 2015-02-17
      • 2015-03-08
      • 2018-12-20
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      相关资源
      最近更新 更多