C++未定义的引用类构造函数

3

我正在尝试使用一个库,其中一个类的构造函数如下:

public:
AreaNodeIndex(size_t cacheSize);

我正在尝试在我的程序中实例化这个类的对象,如下所示:
size_t const cacheSize = 50000;
AreaNodeIndex areaNodeIndex(cacheSize);

链接器给我以下错误:
main.o: In function `main':
make: Leaving directory `/home/Dev/_quicktest_build'
main.cpp:(.text+0x212): undefined reference to  
osmscout::AreaNodeIndex::AreaNodeIndex(unsigned int)

我认为我已经包含了必要的文件,并且通过编译器链接了库。例如,如果我故意尝试不使用任何参数实例化对象,我会得到这个错误:

../quicktest/main.cpp: In function ‘int main()’:
../quicktest/main.cpp:36: error: no matching function for call to ‘osmscout::AreaNodeIndex::AreaNodeIndex()’
/usr/local/include/osmscout/AreaNodeIndex.h:75: note: candidates are: osmscout::AreaNodeIndex::AreaNodeIndex(size_t)
/usr/local/include/osmscout/AreaNodeIndex.h:33: note:     osmscout::AreaNodeIndex::AreaNodeIndex(const osmscout::AreaNodeIndex&)

我可以看到正确的原型(尽管这里说的是size_t,而之前是unsigned int)...

我可以正常使用库的其他部分。以下是涉及该类的实际源文件:

http://libosmscout.git.sourceforge.net/git/gitweb.cgi?p=libosmscout/libosmscout;a=blob;f=libosmscout/include/osmscout/AreaNodeIndex.h

http://libosmscout.git.sourceforge.net/git/gitweb.cgi?p=libosmscout/libosmscout;a=blob;f=libosmscout/src/osmscout/AreaNodeIndex.cpp

我对为什么会发生这种情况感到困惑。我觉得我可能错过了一些显而易见的东西。

*针对回复: 该库从“sys/types.h”获取size_t,因此我认为我们没有使用不同版本的库。该库在我的系统上使用相同的编译器(g++,linux)进行编译。 更改'const'限定符位置没有任何影响。

我正在链接该库。正如我提到的,我可以无问题地使用库中的其他类。这是链接命令:

g++ -Wl,-O1 -Wl,-rpath,/home/QtSDK/Desktop/Qt/473/gcc/lib -o quicktest main.o -L/home/QtSDK/Desktop/Qt/473/gcc/lib -losmscout -lpthread

该库名称为“osmscout”。

kfl


1
这是一个动态库还是静态库?你是在Linux上使用gcc吗,看起来是这样的? - rodrigo
你能否也发布一下这个命令的输出结果:objdump -t libosmscout | c++filt | grep AreaNodeIndex - rodrigo
我是这个库的作者。请联系我解决问题。这可能是由于编译您的代码时错误的编译器选项,导致库中符号导入/导出宏的问题。 - user1008936
5个回答

2
您的问题可能是由于混合使用不同的size_t引起的,正如@rodrigo所提到的。为了保持一致性,除非您的项目声明了自己的typedef来代替size_t,否则在使用size_t时可以包含<cstddef>。请参考下面的链接。
请参考Does "std::size_t" make sense in C++? 希望这可以帮助您!

它是一个标准类型,但它的等价性是“实现定义的”,只要它是无符号的。因此,编译器在不同环境或使用不同编译器选项时有自由更改它。并非明智之举... - rodrigo
@rodrigo:但您不认为,如果在整个源文件中使用<cstddef>中的std::size_t,它将与同一编译器保持一致吗? - another.anon.coward
当然。但是如果库使用不同的编译器版本进行编译呢?或者使用不同的多库模式进行编译呢?或者它可能有一个定义自己的 size_t 的库(已经出现过)? - rodrigo
@rodrigo:是的,你说得对!如果是这种情况,那么可能会变得非常混乱。 - another.anon.coward

1

问题可能在于实际的size_t typedef取决于几个编译器选项。即使在完整的32位机器上,它也可以是unsigned intunsigned long,这取决于开发人员的心情。

因此,如果库是使用typedef unsigned long size_t;编译的,而您的程序是使用typedef unsigned int size_t;,那么就会出现问题。您可以使用objdump -t library | c++filt | grep AreaNodeIndex或类似的命令进行检查。


1
如果这是问题的话,我会感到惊讶。size_t在系统包含文件中定义,应该在任何地方都是相同的。除非他试图将32位库与以64位模式编译的文件链接起来,但在这种情况下,我会期望出现更多的错误。 - James Kanze

0

您没有展示给我们最重要的部分:用于编辑的命令行。您可能没有指定要链接的库(选项-l-L,或者您可以像处理其他文件一样指定库)。

至于链接器指定unsigned int和编译器size_t,那只是错误显示方式的产物:如果在声明函数时使用了typedef,编译器将显示其名称。链接器没有这些信息,因此显示实际类型的名称。


-1

看起来你没有正确地链接库。


-1

你可以试试这个:

const size_t cacheSize = 50000;

吗?

[编辑] 好吧,我猜如果那个声明给你一个无符号长整型,那么可能有一些编译器选项被忽略了,并且在你的编译器中,size_t 被定义为 unsigned long 的 typedef,而不是与库匹配的类型。


这与他已经拥有的语义完全相同。 - Hugh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接