具有C链接的非外部函数

Non-extern function with C linkage

本文关键字:外部 函数 链接 具有      更新时间:2023-10-16

是否可以在没有外部链接的情况下声明具有C链接的函数?当试图编译时

extern "C" static void f() {}

我得到

f.cc:1: error: invalid use of 'static' in linkage specification

这在某种程度上是有道理的。在namespace { extern "C" void f() {} }中,extern说明符似乎覆盖了匿名命名空间的受限范围。

如果这不可能,那么将函数指针传递给C是否重要?

您可以进行

extern "C" {
  static void f() {}
}

这将为函数f提供C类型的链接,这在实践中意味着它在您的平台上使用C调用约定。函数的名称仍将具有C++/内部链接,因为语言链接规范仅适用于外部链接的函数名称。

如果直接在声明中指定extern "C",则Standard指定extern "C"也被视为存储类说明符,因此如果添加static,则会出现冲突。

将函数指针传递给C 是否重要

从理论上讲,这可能很重要——一个实现可以在行为上有所不同,从调用类型具有C++链接的函数到调用类型具有C链接的函数。不过,我不知道实现的细节,只是规范中对它的描述。最好遵循规范,这样你就安全了。

您可以将指向C++非成员或静态成员函数的函数指针传递到C函数中,除非您为该C++函数指定了不同的调用约定,否则应该可以正常工作。常规C++函数应该使用C调用约定,所以您在这方面做得很好。

将指针传递给非静态成员函数并不容易,主要原因是您还需要以某种方式传递有关对象的this指针的信息,这通常是任何成员函数的隐式、不可见参数。

我刚刚成功地使用了Johannes答案。谢谢,伙计!

由于我(还)不能发表评论,但可以回答,所以让我添加这个数据点。

我在<the-file>.cpp中键入(幸运的是省略了详细信息:-):

extern "C" {
    extern int myfunction(<the-args>);
}
extern int myfunction(<the-args>) {
    <the-code>
}

以及:

extern "C" {
    static int myfunction(<the-args>);
}
static int my function(<the-args>) {
    <the-code>
}

我用两种方式编译,并做了一个:

nm -g <the-file>.o | grep myfuncion

依次在两个对象文件上。

我观察到,对于extern,是一个条目,但对于静态情况,则没有。

所以我现在很高兴,外部的"extern"只是建立了链接,而静态情况下的寻址模式是静态的。