我读过Dale Rogerson的书“Inside COM”。在第5章中,他写道(对不起,我用英文翻译):
extern“C”用于C链接。如果函数被标记为 extern“C”, 编译器不会将函数的名称更改为其他名称,例如:
?CreateInstance@@YAPAUIUncnown@@XZ
。
对我来说很清楚。但是,作者进一步在其他地方使用extern "C"
并且没有解释其原因:
#include <objbase.h>
extern "C"
{
// {32bb8320-b41b-11cf-a6bb-0080c7b2d682}
extern const IID IID_IX =
{0x32bb8320, 0xb41b, 0x11cf,
{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;
// {32bb8321-b41b-11cf-a6bb-0080c7b2d682}
extern const IID IID_IY =
{0x32bb8321, 0xb41b, 0x11cf,
{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;
// {32bb8322-b41b-11cf-a6bb-0080c7b2d682}
extern const IID IID_IZ =
{0x32bb8322, 0xb41b, 0x11cf,
{0xa6, 0xbb, 0x0, 0x80, 0xc7, 0xb2, 0xd6, 0x82}} ;
// The extern is required to allocate memory for C++ constants.
}
这不是一个函数......为什么作者在这种情况下使用了extern "C"
?
最诚挚的问候, 安德烈
答案 0 :(得分:4)
非函数上的extern“C”与函数上的extern“C”表示相同;它使对象使用C语义进行命名,以及其他相关内容。
有关详细信息,您可能需要参考标准7.5条链接规范[dcl.link](尽管它是使用困难的英语形式编写的)。
语言链接是为了能够从不同的语言访问声明的实体。这究竟意味着什么取决于特定的语言和C ++实现。传统上使用C表示函数的符号和调用约定已更改。据我所知,在大多数实现中,对于非功能没有任何不同。只是语言规范没有说你可以期望从C中访问这些实体,除非你使用extern“C”。
答案 1 :(得分:0)
对您的问题可能只是一个愚蠢的解决方法。我发现,在cpp文件中使用c函数时,理论上需要extern。但我发现在eclipse氧气版本中,我们不必指定extern c,我们也可以在cpp文件中直接使用c函数和printf语句,它只是工作正常。没有尝试旧版的日食。
我的解决方案可能不是很有帮助,但您可以尝试一下。它对我有用。
据我记得标准,所有函数声明都被视为&#34; extern&#34;默认情况下,因此无需明确指定它。这并不能使这个关键字变得无用,因为它也可以用于变量(在这种情况下 - 它是解决链接问题的唯一解决方案)。但是有了这些功能 - 是的,它是可选的。
更冗长的答案是它允许您使用在另一个源代码文件中编译的变量,但不为该变量保留内存。因此,要利用extern,您必须拥有源代码文件或库单元,其中包含顶层变量(不在函数内)的内存空间。现在,您可以通过在其他源代码文件中定义同名的extern变量来引用该变量。
一般而言,应避免使用extern定义。它们很容易导致无法管理的代码和难以定位的错误。当然,有些例子表明其他解决方案不切实际,但很少见。例如,stdin和stdout是映射到stdin.h中类型为FILE *的extern数组变量的宏;此数组的内存空间位于标准C库单元中。