HI,
我对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文件中说虚拟bool方法...编译test.cpp时没有错误。有人可以解释我做错了什么吗?问题是我有一个模板。使用模板我不能使用virtual..so..i有这个未定义的错误,我不知道如何解决它。 THX
编辑:
当我编译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编译。
答案 0 :(得分:2)
广告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
,则不得在my_code.h
中包含 test.cpp
而不得使用任何内容除了通过dlsym
获取符号之外,定义。因为这是C ++,它反过来要求你理解符号修改方案,因为dlsym
不会为你做这个。
答案 1 :(得分:0)
通常不需要编译.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
};