extern C 不能在类级别使用吗?
只是想确认一下,在Windows环境下,VSTS 2008 + C++项目,我们只能将extern C应用于函数级别,而不能应用于类级别(以便类中的所有成员函数都使用C语言名称修改)? 我尝试了多种方法,但总是编译错误。
提前致谢, 乔治
Just want to confirm in Windows environment, VSTS 2008 + C++ project, we could only apply extern C to function level, not be able to apply to class level (so that all member functions from the class use C language name mangling)? I have tried several ways, but always compile error.
thanks in advance,
George
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
查看您对之前答案的评论(“[M]y 问题只是我们是否可以在类级别应用 extern C 以便类中的所有函数自动具有 C 样式名称修饰?” ,答案是“
extern "C"
不太适合这种方式。”从语法上讲,
extern "C"
可以应用于 curly- 的单个语句。分隔块:通常在整个 C 标头上使用
extern "C"
和适当的#ifdef __cplusplus
防护。从语义上讲,这是应用
extern "C" 的实际效果。 "
只适用于“普通”(即非类)函数和函数指针。当然你不能将其应用于 C++ 模板。也不能将其应用于类方法(因为类方法需要知道它被调用的对象,并且 C 风格的链接没有任何方法将该信息传递给函数)可以应用
extern "C" 存在于命名空间中的函数,但是当通过 C 使用时,命名空间信息将简单地消失。
更新
如果您已经有一个类(我们将使用 POD 类 为简单起见),并且您希望使其可以从 C 语言使用,您需要将
extern "C"
应用于可在 C 中调用的函数。不幸的是,即使在简单的情况下,这也会变得丑陋:使用 gcc 可以按如下方式编译:
g++ try.cc -c -o try.o
gcc try.c try.o
有几个要点:
new
或delete
(或new[]
或delete[]
),您需要将最终程序链接到 C++运行时库(gcc 中的命令行开关是-lstdc++
。显式调用析构函数:
Looking at a comment you placed on a previous answer ("[M]y question is just whether we could apply
extern C
at class level so that all functions in the class automatically has C style name mangling?", the answer is 'extern "C"
doesn't quite work that way.'Syntactically,
extern "C"
can be applied to either a single statement of a curly-delimited block:It's common to use
extern "C"
with the appropriate#ifdef __cplusplus
guards on entire C headers.Semantically, the actual effect of applying
extern "C"
will only apply to "normal" (i.e., non-class) functions and pointers to functions. Of course you cannot apply it to a C++ template. Nor can you apply it to class methods (because a class method needs to know which object it was called on, and C-style linkage does not have any way to pass that information in to the function).It is possible to apply
extern "C"
on functions that exist in a namespace, but the namespace information will simply disappear when used via C.Update
If you already have a class (we'll use a POD class for simplicity), and you want to make it usable from C, you'll need to apply
extern "C"
to a function callable in C. Unfortunately this gets ugly even in simple cases:Using gcc you would compile this as follows:
g++ try.cc -c -o try.o
gcc try.c try.o
There are a few important points:
new
ordelete
(ornew[]
ordelete[]
) you will need to link the final program to the C++ runtime library (the command line switch for this in gcc is-lstdc++
.To call the destructor explicitly:
恐怕不是。 但如果你想将 C++ 的对象传递给 C 函数,你可以参考这个链接:http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.8
I'm afraid not. But if you want to pass an object of C++ to C functions, you may refer to this link: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html#faq-32.8
嗯...
extern "C"
强制 C 风格的链接。 它不能与类 AFAIK 一起使用。Ummm...
extern "C"
forces C-style linkage. It cannot be used with classes AFAIK.您可以通过非常复杂(但完全合法)的 hack 将
extern "C"
应用于成员函数:根据 ISO C++03 9.3[class.mfct]/9,这是可能的:
然而,这并不能真正给你带来任何好处,因为 ISO C++03 7.5[dcl.link]/4:
You can sort of apply
extern "C"
to a member function via a very convoluted (but entirely legal) hack:This is possible according to ISO C++03 9.3[class.mfct]/9:
However, this doesn't really buy you anything, because of ISO C++03 7.5[dcl.link]/4:
extern "c" 使用 c 样式链接; 也就是说,原始函数名称是从库中公开的。 因为它只是一个原始函数名称,所以任何 C++ 专用功能都无法使用它,包括命名空间、类、结构或联合中的方法或外部数据成员。
澄清:结构体和联合体是C语言的,但没有成员函数,因此它们在C++中的成员函数不能以c风格导出(并且结构体和联合体的定义不需要导出,因为它已经在标题中)
extern "c" uses c-style linking; that is, the raw function name is what exposed from the library. Because it is just a raw function name, none of the C++-only features will work with it, including methods or extern data members in namespaces, classes, structs or unions.
Clarifying: Structs and unions are in C, but have no member functions, so their member functions in C++ cannot be exported in a c-style (and the struct and union definitions need not be exported, since it is already in the header)