[英]How to declare an extern C function inside a function in C++?
我有一个内联函数,大致是这样的:
inline void SomeFunction() {
extern void SomeOtherFunction();
SomeOtherFunction();
}
这是一个简化:我的函数确实有参数和返回值。
但是,我希望这个头文件在 C 和 C++ 文件中都可以使用。 目前,链接失败是因为 C++ 文件尝试使用 C++ 链接查找SomeOtherFunction
的实现。 我以为我可以通过使用extern "C"
来解决这个问题:
inline void SomeFunction() {
#ifdef __cplusplus
extern "C" void SomeOtherFunction();
#else
extern void SomeOtherFunction();
#endif
SomeOtherFunction();
}
这会导致 Clang 失败:
error: expected unqualified-id
extern "C" void SomeOtherFunction();
^
我怎样才能正确地做到这一点?
extern "C"
是一个链接规范。 C++ 标准第7.5节链接规范第 4 段指出:
链接规范应仅出现在命名空间范围 (3.3) 中。
例如,您可以在全局名称空间或某些特定名称空间中说extern "C"
。 在命名空间之外,这是非法的。
尽管在较小的范围内,函数声明是可能的。 如果您删除链接规范,您的代码将编译(但不是链接):
inline void SomeFunction() {
extern void SomeOtherFunction();
SomeOtherFunction();
}
如果您确实需要在较小范围内的SomeOtherFunction
声明(例如从全局范围隐藏),您可以将您的声明放入一个专用范围的头文件中,然后在您的函数中使用:
标题:
namespace other {
extern "C" void SomeOtherFunction();
}//namespace other
代码:
void SomeFunction()
{
other::SomeOtherFunction();
}
来自 C++11 标准(在[dcl.link] 中,重点是我的):
4 连杆规格嵌套。 当链接规范嵌套时,最里面的一个确定语言链接。 链接规范不建立范围。 链接规范应仅出现在命名空间范围内。
(链接规范指的是extern string-literal ...
,即extern "C"
在您的情况下。)
这意味着您不能在类或函数中使用extern "C"
。
在SomeFunction
中声明SomeOtherFunction
有什么意义? 它仍然必须是一个全局符号并且对链接器可见。
那么为什么不这样做呢?
#ifdef __cplusplus
extern "C"
#endif
void SomeOtherFunction();
inline void SomeFunction() {
SomeOtherFunction();
}
以下似乎也有效:
extern "C" {
inline void SomeFunction() {
extern void SomeOtherFunction();
SomeOtherFunction();
}
}
但是它会产生副作用,使SomeFunction
也使用 C 链接(希望可以,因为(根据您的要求)它也需要从 C 中可用)。
你可以这样做。 我假设您有一个头文件、一个 C 源代码和一个 C++ 源代码。
头文件:
inline void SomeFunction()
{
void SomeOtherFunction_Bridge();
SomeOtherFunction_Bridge();
}
C++ 源代码:
extern "C"
{
void SomeOtherFunction();
}
void SomeOtherFunction_Bridge()
{
SomeOtherFunction();
}
C源:
void SomeOtherFunction()
{
// Function with a code doing something
}
void SomeOtherFunction_Bridge()
{
SomeOtherFunction();
}
在 GCC 上检查,它编译。
extern
告诉编译器在其他模块中定义了一个符号(函数、变量)。 编译此模块(C++ 文件)时,目标文件包含它需要的外部符号列表。 所以这是在 C++ 文件的级别上,它不能在更小的范围内(函数、块)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.