我正在尝试使用两个大型,复杂的线性代数库来定义许多相同的函数。我无法重写(在一个案例中合法,但在技术上都在两者中)。让我们称它们为“特殊”和“正常”,因为我只调用特殊的几个函数。要始终如一地调用normal.h
中定义的函数,并且仅在某些情况下调用special.h
,我做了类似的事情:
namespace special_space
{
#include "special.h" // Defines foo()
}
#include "normal.h" // Defines foo()
int main() {
foo(); // Calls foo() defined in normal.h
special_space::foo(); // Calls foo() defined in special.h
}
使用g ++ - 4.4,这是我开发它的默认设置,代码编译和链接没有警告,它按照我的预期和我想要的方式执行。这似乎在各种平台,各种Linux,Unix和BSD环境中是一致的。但!如果我使用g ++> 4.4进行编译,我会收到有关多个foo()
定义的警告:
在文件special.h中:: line:col:warning:声明'void special_space :: foo()'与C语言链接[默认启用]
生成的可执行文件然后在调用special_space::foo()
时发生段错误。我/认为/在special.h中找到的定义中指定extern "C++"
可能会解决这个问题,但是我不允许更改special.h。所以我该怎么做?更具体地说:
1)使用g ++ - 4.4是否安全?如果是这样 - 后续版本有什么变化,为什么?
2)如果指定C ++链接模型真的会解决这个问题,有没有办法告诉ld默认使用它?
3)如果这两者都没有 - 是否有另一种方法从定义同名函数的库中调用函数?
答案 0 :(得分:1)
因此,当我发表评论时,将标题包含在
中#ifdef __cplusplus
extern "C" {
#endif
#include normal.h
#ifdef __cplusplus
}
#endif
使用两个标题执行此操作。
基本上,既然你要链接来自c ++的c库,它确实名称为mangling(这是允许重载的),你对c lib中符号的调用就被链接器破坏了。 #ifdef __cplusplus
告诉链接器不要破坏那些特定功能符号的名称。
理想情况下,库的创建者应在其标题中包含此内容,但您提到您无法控制它。我对一些生成的代码有类似的问题。我必须在此包含所有生成的代码,以允许C ++调用它。
我不知道的是,如果没有这个,它是如何运作的。我肯定不得不这样做回到gcc< 4.4。