我正在将用C编写的中型(10,000行左右)程序集成到C ++程序中。我创建了一个新类BWAGenome
作为C代码的接口,因此封装了对C函数的任何访问。我正在使用g++
编译器编译所有内容。 .o文件都是正确生成的,但是当我尝试将它们链接到最终的可执行文件时,编译器会抱怨它找不到符号。这是我收到的错误消息:
Undefined symbols:
BWAGenome::BWTRestoreBWT(char const*)", referenced from:
BWAGenome::BWAGenome(char const*)in BWAGenome.o
"BWAGenome::GetMatches(unsigned int, int, bwt_t*, bwt_t*, bwt_t*, bntseq_t*, bntseq_t*)", referenced from:
BWAGenome::getMatches(unsigned int, int)in BWAGenome.o
这些函数都在我制作的C ++类中。它们将函数包装在C代码中,但我完全不了解这些符号是如何定义的。
关于代码的一些细节以及我到目前为止所做的工作:
g++
进行编译,因此,如果我理解正确,我不需要围绕我包含的c头文件extern "C" {};
。关于如何解决这个问题的任何想法?
<小时/> 编辑:添加BWTRestoreBWT和GetMatches
的定义和声明
//definition in BWAGenome.h
static bwt_t * BWTRestoreBWT(const char *fn);
//declaration in BWAGenome.cpp
static bwt_t * BWTRestoreBWT(const char *fn) {
return bwt_restore_bwt(fn);
//bwt_restore_bwt is a function in the C code that I am attempting to integrate
}
第二次编辑:经过多次灵魂搜索后,我意识到这个问题与我认为的大部分内容完全无关。有关详细信息,请参阅我的回答。
答案 0 :(得分:2)
我注意到它正在寻找BWAGenome::BWTRestoreBWT
和BWAGenome::GetMatches
。这些是它寻找的成员函数,而不是根命名空间全局自由函数。
尝试将要调用C函数的BWTRestoreBWT
调用更改为代码中::BWTRestoreBWT
的调用,看看会发生什么。对GetMatches
的通话也一样。
那个告诉你需要从静态C ++函数调用C函数的人是错误的。这将迫使你将标准库包装在C ++静态函数中,这很愚蠢。
答案 1 :(得分:2)
尝试使用nm程序获取程序中定义和引用的符号输出:
nm file.o | grep BWTRestoreBWT
您应该看到带有T或U的符号.T表示名称已定义,后者表示符号未定义但被调用。为了链接,每个U必须有相应的T。
确保您的函数没有内联限定符,除非它们在头文件中定义。
答案 2 :(得分:2)
我对这个问题的思考越多,看起来你的类声明中声明的函数越多,但你没有相应的函数定义。
例如,此示例编译得很好,但会产生您看到的相同链接器错误:
typedef unsigned int bwt_t;
typedef unsigned int bntseq_t;
class BWAGenome {
public:
BWAGenome( char const* name);
void BWTRestoreBWT( char const* name);
void GetMatches( unsigned int, int, int, bwt_t*, bwt_t*, bwt_t*, bntseq_t*, bntseq_t*);
void getMatches( unsigned int, int);
};
BWAGenome::BWAGenome( char const* name)
{
BWTRestoreBWT( name);
}
void BWAGenome::getMatches( unsigned int x, int y)
{
GetMatches( x, y, 0,0,0,0,0,0);
}
int main()
{
return 0;
}
函数BWTRestoreBWT()
和GetMatches()
应该是class BWAGenome
的一部分还是被包装的C函数?如果是后者,则表明您将这些函数的头部包含在错误的位置(事实上,它们可能需要添加extern "C"
链接规范)。
编辑以回应问题中的新信息:
在您编辑的问题中,您说:
//definition in BWAGenome.h
static bwt_t * BWTRestoreBWT(const char *fn);
//declaration in BWAGenome.cpp
static bwt_t * BWTRestoreBWT(const char *fn) {
return bwt_restore_bwt(fn);
//bwt_restore_bwt is a function in the C code that I am attempting to integrate
}
由于原始问题中存在错误,我只能假设BWTRestoreBWT()
中BWAGenome.h
的声明位于class BWAGenome
内,如此:
class BWAGenome {
// etc...
static bwt_t * BWTRestoreBWT(const char *fn);
// etc...
};
这意味着BWTRestoreBWT()
是class BWAGenome()
的成员,因此其定义应如下所示(请注意BWAGenome::
作用域操作符):
//declaration in BWAGenome.cpp
static bwt_t * BWAGenome::BWTRestoreBWT(const char *fn) {
return bwt_restore_bwt(fn);
//bwt_restore_bwt is a function in the C code that I am attempting to integrate
}
或者您可以将BWTRestoreBWT()
的声明移到class BWAGenome
之外(更正式地称为“命名空间范围”)。
那应该修复你当前的链接器错误。如果您现在收到有关名称类似于bwt_restore_bwt
但未找到的内容的错误,那么您也知道您需要为C函数执行extern "C"
。
答案 3 :(得分:1)
您是否告诉链接器在哪里可以找到包含BWAGenome::BWTRestoreBWT
函数的库/对象?由于您单独编译所有内容,因此必须明确链接输出.o文件。
可能导致此链接错误的两个原因是
答案 4 :(得分:1)
如果将static关键字与非类成员函数一起使用,该函数将具有本地链接,这意味着它不会在编译单元外部显示,即.cpp文件。 你要么必须得到静态关键字,要么将函数体放入你的包含文件中。
在类成员函数的上下文中,static具有不同的含义。在这种情况下,static允许在不实例化类对象的情况下调用函数。
答案 5 :(得分:0)
您是否检查过您确实声明了相同形状的功能?
它正在寻找BWAGenome::BWTRestoreBWT(char const*)
,但您可能会声明BWAGenome::BWTRestoreBWT(char *)
(没有const
)吗?
答案 6 :(得分:0)
错误是我将目标文件链接在一起的顺序。我需要首先链接C代码,然后我创建的BWAGenome类来调用它。链接器找不到C代码符号,因为它们尚未链接。谢谢你的帮助。我想我有些人感到沮丧,但不管怎样,谢谢。