我现在有一个让我感到困惑的问题: 我有一些用C ++编写的软件,它链接到C中的库。我使用通常的
包含头类extern "C" {
#include <libheader.h>
}
只要我不使用gcc的优化,一切正常。一旦我打开偶数-O1,即第一个优化级别,在运行期间我得到一个来自该库的符号的“未定义符号”错误。但是,该名称已经过名称修改,应该禁用extern "C"
。
如果这很重要,则会内联调用有问题符号的函数。使用的编译器是gcc 4.4.3。
老实说,我甚至不知道该搜索什么,所以如果你们中的一个人能给我一些理由来表达这种行为,我将非常感激。
感谢您的支持。
答案 0 :(得分:4)
您说您将libheader.h
文件包含在extern "C"
块中,但链接器正在查找的符号已被命名为。
这表明libheader.h
也被包含在extern "C"
块之外(extern "C"
块内的包含可能是一个nop,因为libheader.h
中包含了警卫)。
寻找可能包含libheader.h
的其他方式。 GCC的-E
和/或各种-M
选项可能对此有帮助,也可能没有帮助。或者(如果仅用于测试)移动extern "C"
内的libheader.h
块:
// at start of libheader.h:
#ifdef __cplusplus
extern "C" {
#endif
/* existing contents of libheader.h */
// ...
// at end of libheader.h:
#ifdef __cplusplus
}
#endif
请注意,链接规范可以嵌套,因此您无需删除extern "C"
网站上的现有#include
块。
我不知道为什么问题只会发生在优化的构建中,除了包含调用函数的非内联版本的.c或.cpp文件可能会使头部正确,并且只需要一个转换单元,它解决了标题错误并内联调用函数以查看问题。
答案 1 :(得分:3)
如果你有一个未内联但未内联时定义的函数,那么定义问题应该非常简单。
您已在某处使用该功能,但未包含其头文件。
查看调用此函数的所有文件,并确保包含标题。
答案 2 :(得分:1)
定义调用内联函数的头是否可能包含库的标题而不使用 extern "C"
包装器,以及使用包装行的其他地方?
您是否尝试过其他级别,例如-O2
?
您是否尝试过取消功能?
答案 3 :(得分:0)
使用extern "C" {...}
包装C标头并不总是有效;
通常,标题需要设计为使用两种语言
他们使用这两种语言。
在这种情况下,没有更多细节,很难确切地说是什么
正在发生,但是 inline
关键字在C和in中意味着不同的东西
C ++;我不希望带有inline
函数的标头在此工作
办法。 (手头,我不会指望你得到的症状,但他们
也不要特别让我感到惊讶。)
正确的处理方法是坚持供应商 库提供了一个标题,旨在使用两种语言。
如果做不到这一点,处理这个的正确方法就是自己编写 C代码,包括标题并包装您的所有功能 需要,并为此C代码编写自己的标头,这是为了设计 包含在两种语言中。我承认,这是很多工作; 让供应商完成他的工作,而不是做一半的工作 他。