c++ - C的 "extern"是怎么工作的?

标签 c++ c

我有一个 C/C++ 程序,它是 Firefox 的插件。因为它是一个插件,所以它有非主入口点。这些入口点需要在 C 中编译,否则它们的名称会被破坏。但是,其他函数会过载,因此它们需要是 C++。解决方案是外部“C”。我已经想通了。

但是,如果我在 .c 文件周围使用 extern“C”,我会收到链接错误,因为 C++ 文件的名称被破坏了,但 .c 文件中的调用却没有。至少我认为这就是正在发生的事情。

解决方案似乎是将 extern "C"放在 .h 文件周围。这似乎意味着在 .h 文件中声明的函数的名称没有被破坏,即使它们是在(可能被破坏的).c 文件中定义的。

但是,我不明白为什么这会起作用。这是拼团吗?我是否为以后很难发现的错误做好了准备?或者这是解决这个问题的正确方法?

最佳答案

最不令人困惑的事情(至少对我而言)是使 header 中的声明与函数定义相匹配。正如其他答案所提到的,最重要的是声明/原型(prototype) - 只要编译器已经“看到”原型(prototype),就可以从函数定义中省略 extern "C" 链接规范当它到达定义时。但是,我个人认为让声明和定义匹配更可取,而且可能不会造成混淆,但这是其他程序员可能不认同的偏好。

请注意,您不必 extern "C" header 或实现文件中的所有内容 - extern "C" 可以应用于单个名称或到一组名称(通过将其应用于 block )。

所以,在你的标题中你可以有这样的东西:

// entrypoints.h

#ifdef __cplusplus
// this opens an extern "C" block, but only if being included for a C++ compile
//  if this is being included in a C compile, the extern "C" bits won't be seen
extern "C" {
#endif

int foo(void);
int bar( void*);


#ifdef __cplusplus
// close the extern "C" block, but only if we started it in the first place
}
#endif

以及您对它们的实现:

// entrypoints.cpp

// Note: since this is a .cpp file, it's compiled as C++ so we
//  don't need the #ifdefs around the extern "C"

#include "entrypoints.h"

extern "C"
int foo(void)
{
    return 42;
}


extern "C"
int bar( void* p)
{
    return -42;
}

关于c++ - C的 "extern"是怎么工作的?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2238456/

相关文章:

c++ - 释放有效的 SDL 表面会导致段错误

c - 跳转到数据段

c - 检测不匹配的数组 <-> 枚举初始值设定项

c++ - 后缀(前缀)增量、左值和右值(在 C 和 C++ 中)

将 float 与整数进行比较

C - 一个奇怪的 Seg 错误

C++ 复制构造函数的奇怪行为

c++ - std::regex_error - 意外的转义字符

c++ - 为什么C++在对Foo <T>::Foo(T &&)的调用中不能推断T?

c++ - 如何将基于通用迭代器的算法与基于实现的算法结合起来?