简体   繁体   English

gcc 4.4与gcc> 4.4中的默认链接模型

[英]Default linkage model in gcc 4.4 vs. gcc >4.4

I'm trying to use two large, complex linear algebra libraries which define many of the same functions. 我正在尝试使用两个大型复杂的线性代数库来定义许多相同的函数。 I can't rewrite (legally in one case, but technically in both) either of them. 我无法重写(在一个案例中合法,但在技术上都在两者中)。 Let's call them "special" and "normal" because I only call a couple functions from special. 让我们称它们为“特殊”和“正常”,因为我只调用特殊的几个函数。 To consistently call functions defined in normal.h and only in some cases from special.h , I've done something like this: 要始终如一地调用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
}

With g++-4.4, which was the default where I was developing this, the code compiles and links without warnings, and it executes as I would expect and as I want. 使用g ++ - 4.4,这是我开发它的默认设置,代码编译和链接没有警告,它按照我的预期和我想要的方式执行。 This seems to be consistent across platforms, various Linux, Unix and BSD environments. 这似乎在各种平台,各种Linux,Unix和BSD环境中是一致的。 But! 但! if I compile with g++ >4.4, I get warnings about multiple foo() definitions: 如果我使用g ++> 4.4进行编译,我会收到有关多个foo()定义的警告:

In file special.h::line:col: warning: declaration of 'void special_space::foo()' with C language linkage [enabled by default] 在文件special.h :: line:col:warning中:使用C语言链接声明'void special_space :: foo()'[默认启用]

The resulting executable then segfaults at the call to special_space::foo() . 生成的可执行文件然后在调用special_space::foo() I /think/ that specifying extern "C++" in the definitions found in special.h might fix this, but I'm not allowed to change special.h. 我/认为/在special.h中找到的定义中指定extern "C++"可能会解决这个问题,但是我不允许更改special.h。 So what should I do? 所以我该怎么做? More specifically: 进一步来说:

1) Is it safe to use g++-4.4? 1)使用g ++ - 4.4是否安全? If so -- what changed in subsequent versions and why? 如果是这样 - 后续版本有什么变化,为什么?

2) If specifying the C++ linkage model really would fix this, is there a way to tell ld to use it by default? 2)如果指定C ++链接模型真的会解决这个问题,有没有办法告诉ld默认使用它?

3) If neither of those -- is there another way to call functions from libraries that define functions of the same name? 3)如果这两者都没有 - 是否有另一种方法从定义同名函数的库中调用函数?

So as I posted in a comment, wrap the headers includes with 因此,当我在评论中发布时,包括标题包括

#ifdef __cplusplus
extern "C" {
#endif

#include normal.h

#ifdef __cplusplus
}
#endif

Do this with both headers. 用两个标题执行此操作。

Basically, since you're linking c libraries from c++, which does name mangling (this is what allowes overloading), your calls to the symbols in your c lib were being mangled by the linker. 基本上,既然你要链接来自c ++的c库,它确实名称为mangling(这是允许重载的),你对c lib中符号的调用就被链接器破坏了。 The #ifdef __cplusplus tells the linker not to mangle the names for those specific function symbols. #ifdef __cplusplus告诉链接器不要#ifdef __cplusplus那些特定功能符号的名称。

Ideally, the creators of the library should include this in their headers but you mentioned that you have no control over that. 理想情况下,库的创建者应在其标题中包含此内容,但您提到您无法控制它。 I had a similar problem with some generated code. 我对一些生成的代码有类似的问题。 I had to wrap all my header includes of the generated code in this to allow C++ to call it. 我必须将我生成的代码包含在此包含生成的代码,以允许C ++调用它。

What I don't know, is how it ever worked without this. 我不知道的是,如果没有这个,它是如何运作的。 I've definitely had to do this going back to gcc < 4.4. 我肯定要回到gcc <4.4。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM