C++ 声明一个C++;具有C调用约定但内部链接的函数

C++ 声明一个C++;具有C调用约定但内部链接的函数,c++,c,extern,linkage,cross-language,C++,C,Extern,Linkage,Cross Language,我正在尝试与一个C库接口,它希望我提供一个指向回调函数的指针 据我所知,根据标准,回调必须有C语言链接,因为可能有不同的调用约定。我可以通过将回调函数声明为extern“C”来实现这一点。然而,这有一个不良的副作用:将函数的非限定和未混合的名称暴露给其他翻译单元 是否有可能声明一个函数,使其名称具有内部链接(不可见于其他翻译单元),但它可以通过C(仅使用标准C++约定)调用(具有适当调用约定)的C调用? 如果不能使它具有内部链接,那么至少有可能使它保持C++名称的弱化吗?< /P> 我试过:

我正在尝试与一个C库接口,它希望我提供一个指向回调函数的指针

据我所知,根据标准,回调必须有C语言链接,因为可能有不同的调用约定。我可以通过将回调函数声明为
extern“C”
来实现这一点。然而,这有一个不良的副作用:将函数的非限定和未混合的名称暴露给其他翻译单元

是否有可能声明一个函数,使其名称具有内部链接(不可见于其他翻译单元),但它可以通过C(仅使用标准C++约定)调用(具有适当调用约定)的C调用? <>如果不能使它具有内部链接,那么至少有可能使它保持C++名称的弱化吗?< /P> 我试过:

  • 将其声明为
    静态外部“C”void f()导致编译错误,导致
    静态
    外部“C”
    不能一起使用
  • 在匿名名称空间中将其声明为
    名称空间{extern“C”void f();}
    ,结果与常规名称空间具有相同的效果,从而公开了未混合的非限定名称
上面的代码编译得非常好。符号在翻译单元外不可见,您可以通过指针调用函数


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

无需声明函数
extern“C”
。只需要函数接受指向具有适当参数类型和返回类型的函数的指针。接受指向函数的指针的函数不会从调用方获取有关传递函数名称的信息(损坏或其他信息)。显然,这些类型必须在C中有效。我假设您没有使用任何编译器特定的关键字或调用约定。仅供参考:@Peter在上到下一页如何?声称调用约定在C和C++函数之间可能不同,因此在<代码>外部“C”{<代码> >代码> } /代码>中声明函数似乎更安全。这里有一些讨论:@yurikilochek你能详细说明一下吗?我会顺便引用
当两个具有相同非限定名称的函数在不同的命名空间中声明,并且都有“C”语言链接时,声明引用相同的函数
。从godbolt链接猜测,也许这就是让OP困惑的地方。试着从不同的翻译单元调用它。我自己试过了,得到了一个未定义的引用错误,这意味着这个解决方案是有效的,适用于所有情况。我不明白。该函数有内部链接和C调用约定,证明了它是可能的。@ YurikooCKK仍然,您的<代码> f>代码>函数将不能从另一个文件访问,因此您可以将它和C++函数引用到一个单独的文件中并调用它一天。我认为这里是gcc,它根据标准做了正确的事情。
extern "C" {

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

}