[英]How to declare an extern C function inside a function in C++?
I have an inline function, roughly like this:我有一个内联函数,大致是这样的:
inline void SomeFunction() {
extern void SomeOtherFunction();
SomeOtherFunction();
}
This is a simplification: my functions do have parameters and return values.这是一个简化:我的函数确实有参数和返回值。
However, I want this header to work in both C and C++ files.但是,我希望这个头文件在 C 和 C++ 文件中都可以使用。 Currently, linking fails because C++ files attempt to find an implementation of SomeOtherFunction
with C++ linkage.目前,链接失败是因为 C++ 文件尝试使用 C++ 链接查找SomeOtherFunction
的实现。 I thought I could just fix this by using extern "C"
:我以为我可以通过使用extern "C"
来解决这个问题:
inline void SomeFunction() {
#ifdef __cplusplus
extern "C" void SomeOtherFunction();
#else
extern void SomeOtherFunction();
#endif
SomeOtherFunction();
}
This causes Clang to fail with:这会导致 Clang 失败:
error: expected unqualified-id
extern "C" void SomeOtherFunction();
^
How can I do this correctly?我怎样才能正确地做到这一点?
extern "C"
is a linkage-specification . extern "C"
是一个链接规范。 C++ standard section 7.5 Linkage specifications paragraph 4 states that: C++ 标准第7.5节链接规范第 4 段指出:
A linkage-specification shall occur only in namespace scope (3.3).链接规范应仅出现在命名空间范围 (3.3) 中。
Eg you can say extern "C"
in global namespace or some specific namespace.例如,您可以在全局名称空间或某些特定名称空间中说extern "C"
。 Outside of namespaces it is illegal.在命名空间之外,这是非法的。
Function declarations are possible though in smaller scopes.尽管在较小的范围内,函数声明是可能的。 If you remove linkage specification your code will compile (but not link):如果您删除链接规范,您的代码将编译(但不是链接):
inline void SomeFunction() {
extern void SomeOtherFunction();
SomeOtherFunction();
}
If you really need SomeOtherFunction
declaration in a smaller scope (eg hide from global scope) you can put your declaration into a header file to a dedicated scope and then use in your function:如果您确实需要在较小范围内的SomeOtherFunction
声明(例如从全局范围隐藏),您可以将您的声明放入一个专用范围的头文件中,然后在您的函数中使用:
Header:标题:
namespace other {
extern "C" void SomeOtherFunction();
}//namespace other
Code:代码:
void SomeFunction()
{
other::SomeOtherFunction();
}
Credit goes to these two answers on stackoverflow: here and here .归功于 stackoverflow 上的这两个答案: here和here 。
From the C++11 standard (in [dcl.link] , emphasis mine):来自 C++11 标准(在[dcl.link] 中,重点是我的):
4 Linkage specifications nest. 4 连杆规格嵌套。 When linkage specifications nest, the innermost one determines the language linkage.当链接规范嵌套时,最里面的一个确定语言链接。 A linkage specification does not establish a scope.链接规范不建立范围。 A linkage-specification shall occur only in namespace scope .链接规范应仅出现在命名空间范围内。
( linkage-specification refers to extern string-literal ...
, ie extern "C"
in your case.) (链接规范指的是extern string-literal ...
,即extern "C"
在您的情况下。)
This means you can't have extern "C"
inside of a class or function.这意味着您不能在类或函数中使用extern "C"
。
What's the point of declaring SomeOtherFunction
inside of SomeFunction
?在SomeFunction
中声明SomeOtherFunction
有什么意义? It still has to be a global symbol and visible to the linker.它仍然必须是一个全局符号并且对链接器可见。
So why not do this?那么为什么不这样做呢?
#ifdef __cplusplus
extern "C"
#endif
void SomeOtherFunction();
inline void SomeFunction() {
SomeOtherFunction();
}
The following also seems to work:以下似乎也有效:
extern "C" {
inline void SomeFunction() {
extern void SomeOtherFunction();
SomeOtherFunction();
}
}
But it would have the side effect of making SomeFunction
also use C linkage (which is hopefully OK as (per your requirements) it needs to be usable from C, too).但是它会产生副作用,使SomeFunction
也使用 C 链接(希望可以,因为(根据您的要求)它也需要从 C 中可用)。
You can do this like that.你可以这样做。 I assume you have a header file, a C source and a C++ source.我假设您有一个头文件、一个 C 源代码和一个 C++ 源代码。
Header file:头文件:
inline void SomeFunction()
{
void SomeOtherFunction_Bridge();
SomeOtherFunction_Bridge();
}
C++ source: C++ 源代码:
extern "C"
{
void SomeOtherFunction();
}
void SomeOtherFunction_Bridge()
{
SomeOtherFunction();
}
C source: C源:
void SomeOtherFunction()
{
// Function with a code doing something
}
void SomeOtherFunction_Bridge()
{
SomeOtherFunction();
}
Checked on GCC, it compiles.在 GCC 上检查,它编译。
extern
tells the compiler that a symbol (function, variable) is defined in some other module. extern
告诉编译器在其他模块中定义了一个符号(函数、变量)。 When this module (C++ file) is compiled, object file contains a list of external symbols it needs.编译此模块(C++ 文件)时,目标文件包含它需要的外部符号列表。 So this is on a level of a C++ file, it cannot be in smaller scope (function, block).所以这是在 C++ 文件的级别上,它不能在更小的范围内(函数、块)。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.