几乎所有关于SO的问题最终都会得到MSVC(def文件或/ EXPORT链接选项)的答案。
然而有几个提到gcc:
How can i avoid name mangling?在源代码中使用asm()
提及一次。由于我对装配不熟悉,我对使用它有点犹豫。
How do I stop name-mangling of my DLL's exported function?在编译/链接过程中提到使用-Wl,--kill-at
选项。但是,我无法在任何gcc或链接手册页中找到这样的内容。
那么,有没有办法在不使用extern "C"
的情况下避免使用C ++进行名称修改?
谢谢。
[编辑]
class Base
{
public:
virtual void Foo() = 0;
};
class Derived : public Base
{
public:
virtual void Foo() {};
};
extern "C" Base *MyExportedFunc()
{
Base *pb = new Derived();
return pb;
}
没有extern“C”MyExportedFunc()将具有C ++链接,名称将被破坏。因此,我无法简单地从C ++代码中调用它。 对于extern“C”,函数是C-linkage。但是那时函数不会知道Base - >衍生的关系。因此,函数的调用者只会在内存中看到一个地址。这是一个C函数。
希望现在很清楚。
[/编辑]
答案 0 :(得分:3)
有没有办法避免使用C ++中的名称修改而不使用extern" C"?
没有。您可以使用某些编译器以非便携方式为某些功能执行此操作。在正常的C ++开发中从不需要这样做。
没有extern" C" MyExportedFunc()将具有C ++链接,名称将被破坏。 因此我无法简单地从C ++代码中调用它。
这是不正确的。您可能无法使用dlsym
之类的函数轻松找到它,这几乎不符合从C ++代码中调用它的条件。正常链接和调用不是问题。
使用extern" C"功能是C-linkage。 但是这个函数不会知道Base - >衍生的关系。
这也是不正确的。 extern "C"
并不排除函数使用任何C ++特性。
总结:创建普通(链接)C ++库的常见做法是不考虑名称错误。创建插件(与dlsym
/ GetProcedureAddress
一起使用的可加载库)的常见做法是使用extern "C"
。