2011-03-30 65 views
6

我现在有一个问题,让我感到困惑: 我有一段以C++编写的软件,并且与C中的库链接。通常的在运行时GCC优化结果为“未定义符号”

extern "C" { 
    #include <libheader.h> 
} 

一切正常,只要我不使用gcc的优化。一旦我打开-O1(因此是第一个优化级别),在运行期间,我会从该库中获取符号的“未定义符号”错误。但是,这个名字已经通过名称修改,应该被禁用,因为extern "C"

调用符号的函数被内联,以防万一。使用的编译器是gcc 4.4.3。

我真的不知道要搜索什么,所以如果你们其中一个可以给我一些这种行为的理由,我会非常感激。

感谢您的支持。

+0

你可以删除内联(即使功能不内联),看看它是否开始工作? – sashoalm 2011-03-30 12:08:50

+1

作为@ satuon的建议的替代方法,是否可以让内联函数调用一个包装C函数的C++函数,并查看它是否能够开始工作? – 2011-03-30 12:11:11

+0

感谢您的回复!我尝试了两个建议,但是,该符号仍未找到。 – Thilo 2011-03-30 13:38:09

回答

1

是否有可能定义调用内联函数头包括库的头没有extern "C"包装,和其他地方使用的包装线?

您是否试过其他等级-O2

您是否尝试取消内定功能?

+0

感谢您的想法。是的,正确文件的头文件肯定使用'extern“C”'wrapper。 -O2和-O3具有相同的效果。如上所述,删除内联也无济于事。 – Thilo 2011-03-30 13:57:42

+0

@Thilo具体来说,你删除了内联,并将头文件中的函数移动到源文件中,这样编译器就不能决定自动内联它了吗? – 2011-03-30 14:31:07

+0

呃...谢谢你澄清。忘记将先前内嵌的函数移至源文件。这解决了这个问题。但是,结果并不是很优雅,因为内联函数可能会更快。 – Thilo 2011-04-08 06:02:58

3

如果您有一个函数在未内联时定义但在内联时未定义,那么该问题应该很容易定义。

你已经使用了某个地方的函数而不包含它的头文件。

查看所有调用此函数的文件,并确保包含标题。

0

extern "C" {...}包装C头并不总是有效; 通常,标题需要被设计为与两种语言一起工作,以便 他们能够使用这两种语言。

在这种情况下,没有更多的细节,这是很难说究竟是什么 发生,inline关键字意味着C和在 C++不同的东西;我不希望带有inline函数的标题以这种 方式工作。 (我不希望出现症状,但他们 也不会让我感到意外。)

处理此问题的正确方法是坚持要求 库的供应商提供标题,旨在用这两种语言工作。

如果不成功,处理这个问题的正确方法是编写自己的 C代码,它包含头文件并包装所有需要的函数,并为此C代码编写自己的头文件至 包括在两种语言中。我承认,这是很多工作; 得到供应商做他的工作,而不是他的一半为 他。

4

你说你在extern "C"块中包含libheader.h文件,但链接器正在寻找的符号已经被名字弄乱了。

就是这样libheader.h也被包括在extern "C"块外的指示(在包括内部的extern "C"块可能是由于包括在libheader.h警卫一个NOP)。

寻找可能包含libheader.h的其他方法。海湾合作委员会的-E和/或各种-M选项可能有助于解决这个问题。或者(如果仅用于测试)移动内部libheader.hextern "C"块:

// at start of libheader.h: 
#ifdef __cplusplus 
extern "C" { 
#endif 

/* existing contents of libheader.h */ 
// ... 

// at end of libheader.h: 
#ifdef __cplusplus 
} 
#endif 

需要注意的是联动的规格可以嵌套,所以你不必在#include网站删除现有extern "C"块。

我不知道为什么这个问题只会发生在优化构建中,不同之处在于包含调用函数的非内联版本的.c或.cpp文件可以正确获取标题,并且只需要成为一个翻译单元,它会使标题错误,并调用调用函数来查看问题。

+0

谢谢!如果这就是原因,那么如何找出问题可能是一个好主意。可悲的是,我只有在下周星期五才有时间研究它,会在那时报告。 – Thilo 2011-03-31 07:09:05

相关问题