首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用外部"C“链接的重载解析

使用外部"C“链接的重载解析
EN

Stack Overflow用户
提问于 2011-02-02 01:44:29
回答 4查看 8.8K关注 0票数 13

在C/C++混合项目中,我们需要从C调用一个C++函数。要调用的函数被重载为三个单独的函数,但我们可以从C端忽略这一点,我们只选择最合适的一个并坚持使用该函数。

有两种方法可以做到这一点:(1)用外部"C“函数编写一个小的C++包装器,将调用转发给所选的重载函数,或者(2)用一种老套的方法,只将我们想要从C调用的一个函数声明为外部"C”。

问题是,第二个变种有什么缺点(除了噩梦和恶业)吗?换句话说,给出三个重载函数,其中一个被声明为"C",我们应该期待C++方面的麻烦,或者这是根据标准定义的吗?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2011-02-02 01:48:44

我相信标准中的语言是专门编写的,只允许一个带有"C“链接的函数,以及任意数量的带有"C++”链接的重载相同名称的其他函数(§dcl.link/6):

最多只有一个具有特定名称的函数可以有C语言链接。具有相同函数名(忽略限定它的名称空间名)的具有C语言链接的函数的两个声明出现在不同的名称空间作用域中,它们引用同一个函数。具有相同名称(忽略限定它的名称空间名称)的具有C语言链接的对象的两个声明出现在不同的名称空间作用域中,它们引用同一个对象。

该标准如下所示:

代码语言:javascript
运行
复制
complex sqrt(complex); // C + + linkage by default
extern "C" {
    double sqrt(double); // C linkage
}
票数 21
EN

Stack Overflow用户

发布于 2011-02-02 01:51:09

即使标准允许,将来的代码维护者也可能会非常困惑,甚至可能删除外部的"C",破坏C代码(可能过了很久,事件就不能链接了)。

只需编写包装器即可。

编辑:从C++03 7.5/5:

如果同一函数或对象的两个声明指定了不同的链接规范(即这些声明的链接规范指定了不同的字符串文字),则如果这两个声明出现在同一个翻译单元中,则程序是错误的,如果这两个声明出现在不同的翻译单元中,则适用one definition规则(3.2) ...

我将此解释为不适用,因为具有相同名称的C和C++函数实际上不是相同的函数,但这种解释可能是错误的。

然后从C++03 7.5/6开始:

最多只能有一个具有特定名称的函数具有C语言链接...

这意味着您可以有其他具有相同名称的非C链接函数。在这种情况下,C++会重载。

票数 2
EN

Stack Overflow用户

发布于 2011-02-02 02:09:14

只要您遵循extern-C函数的其他规则(比如它们的特殊名称要求),根据标准将其中一个重载指定为extern-C就可以了。如果您碰巧使用指向这些函数的函数指针,请注意语言链接是函数类型的一部分,需要指向此函数的函数指针可能会决定您的问题。

否则,我看不到任何明显的缺点。即使复制参数和返回值的潜在缺点也可以通过编译器和实现细节来缓解,这些细节允许您内联函数-如果这被确定为问题的话。

代码语言:javascript
运行
复制
namespace your_project {  // You do use one, right? :)
  void f(int x);
  void f(char x);
  void f(other_overloads x);
}

extern "C"
void f(int x) {
  your_project::f(x);
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/4866043

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档