[英]c++ undefined reference to <a function>
嗨,
我对c ++ / linux(ubuntu)中的.h文件和.cpp文件有一些疑问。
可以使用g ++编译.h文件,也可以只编译包含.h文件的.cpp文件?
从.h文件开始,然后是.cpp文件(在.cpp中,其中包括一些我在.h文件中定义的方法的代码),我使用以下命令创建.so文件:
g++-fPIC -shared my_code.cpp -o my_code.so`
在test.cpp
我包括.h文件,并使用dlopen在.so文件上创建处理程序。 为什么会有以下错误:
undefined reference to bool `Class::method(std::string)` `collect2: ld returned 1 exit status
如果我说虚拟布尔方法...在.h文件中,则在编译test.cpp时没有错误。 有人可以解释我在做什么错吗? 事情是,我有一个模板。 有了模板,我无法使用virtual..so..i出现此未定义错误,并且我不知道如何解决。 谢谢
编辑:
当我编译my_code.cpp
出现错误:
/usr/bin/ld: .usr/lib/debug/usr/lib/crt1.o relocation 0 has invalid symbol index 12 (same with index 13,2,14...22 ).
但是,当我创建.so
文件时,没有错误。 我用:
g++ test.coo -ldl -o test
用于test.cpp编译。
广告1:可以编译.h
文件(您可以显式覆盖语言检测),但是您不想这样做。 .h
文件旨在被包括在内,并且不能单独编译成任何有用的东西。
广告2:您必须通过传递-lmy_code
链接到创建的库(但要注意,要使其正常运行,您必须将其创建为libmy_code.so
)以及适当的-L
标志(放置libmy_code.so
目录)链接器。 像这样:
g++ test.cpp -L. -lmy_code -ldl -o test
但是,您还必须将第一个命令更改为:
g++ -fPIC -shared my_code.cpp -o libmy_code.so
^^^
libraries *must* have `lib` prefix on unix systems.
并且假定两者都在同一个目录中完成-如果不同,则必须调整-L
选项以指向libmy_code.so所在的目录。 另外,您还必须将libmy_code.so
放置在动态链接程序可以找到它的位置。 通过安装它或将环境变量LD_LIBRARY_PATH
设置为适当的目录。 或者,您可以使用以下命令进行编译
g++ test.cpp my_code.so -ldl -o test
这不会强制使用lib
前缀,它会在二进制文件中创建一个“ rpath”条目,因此它将在原始位置找到该库。
所有这些都假定您要将其用作常规库,在这种情况下,您不想使用dlopen 。 dlopen
用于在运行时将库作为插件打开,然后只能通过使用dlsym()
获取指向符号的指针来访问它们,但是如果要正常访问该库,则必须对其进行链接,以便链接器可以解析这些符号。
相反,如果您想使用dlopen
,则必须不要在test.cpp
包含 my_code.h
,并且不得使用其定义的任何内容,除非使用dlsym
获取符号。 由于这是C ++,因此又需要您了解符号处理方案,因为dlsym
不会为您执行此操作。
通常,不需要编译.h
文件,它只是生成一个扩展名为.gch
的巨大文件。
您得到的错误是链接时间。 创建.so
文件时,您实际上并未链接代码。 因此,所有未定义的符号都假定存在于某个位置。 链接时,链接器将查找这些符号。 因此,您应该将所有.cpp文件编译/链接在一起。 错误将消失。
另外,对于templates
, 代码的定义必须始终可见 。 因此,无论您在何处编写模板化函数/变量定义,都应在任何地方包含该文件。
编辑 :您可以使用带有模板类的virtual
方法; 但是您不能使用virtual template methods
。
template<typename T>
class A {
virtual void foo(int); // ok
};
class A {
template<typename T>
virtual void foo(T); // illegal
};
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.