【发布时间】:2023-03-28 06:05:02
【问题描述】:
我有一个编译成 .so 文件的 c++ 项目(使用 g++5 编译)。 在另一个项目中(在同一解决方案下)我有一个链接到该项目的测试(CMake 的命令 target_link_libraries(...))。
我编译项目,并将输出的 .so 文件复制到“/tmp/proj.so”。
除了将测试链接到项目之外,我还使用dlopen动态加载“/tmp/proj.so”,它有一个全局函数create_foo,它创建了一个新的foo对象。
我想要实现的目标是进行一项测试,将同一项目的两个版本与另一个版本进行比较,这样我就知道我不会因为更改项目中的内容而破坏任何东西。
用dlopen打开后,我调用dlsym找到create_foo,然后调用它。
create_foo is 类似:
extern "C" bool create_foo(foo** instance){
*instance = new foo();
return true;
}
所以在我的测试中我有类似的东西(我删除了不相关的代码,如空检查):
#include <dlfcn.h>
#include "foo.h"
int main()
{
foo f1;
void* handle = dlopen("/tmp/proj.so", RTLD_NOW);
bool(*create_foo_func)(foo**);
create_foo_func = (bool(*)(foo**))dlsym(handle, "create_foo");
foo* f2;
(*create_foo_func)(&f2);
assert(f1.bar() == 10);
assert(f2->bar() == 10);
}
两个断言都可以。
所以接下来我将foo::bar改为return 5而不是10,编译了项目但我没有更改/tmp/proj.so文件!
当我运行程序时,我得到了:
f1.bar() == 5
f2->bar() == 5 //I would expect this to be 10 since I did not change it
所以我在两个电话中都得到了5,而不是我希望的f1.bar()==5 和f2->bar() == 10。
我确定 dll 正在加载并且动态中的 create_foo 被调用(我可以在调试器的模块列表中看到它,并且如果我尝试 dlsym("NOT_create_foo") 它会失败,另一种方式也失败,即将 create_foo 函数名更改为某事但不更改 /tmp/proj.so)。
当我在代码中添加 printf("static links"),编译它并保持 /tmp/proj.so" 文件不变(意味着它没有这个 printf)时,我看到它被打印了两次。
那么我在这里做错了什么?
我正在处理的实际项目很大并且正在使用 CMake。我可能遗漏了我认为不相关的重要细节,如果您认为我应该在某个地方查看,请发表评论,我将编辑答案。
【问题讨论】:
-
foo::bar函数是在foo类中内联定义的吗?或者您的应用程序是否与包含foo::bar定义的(修改后的)源文件链接? -
@Some 程序员老兄, foo::bar 不是内联的。它与定义一起编译。另请注意,问题始于构造函数。即当我在 ctor 中打印 f1 和 f2 打印时,尽管我没有复制修改后的 .so
-
澄清一下。
foo类的实现在您的程序中,而不是库中。因此,您对其所做的任何更改都将在您的程序中。该库真正做的只是创建一个实例,该实例的函数已经在您的程序中。 -
我习惯了 Visual Studio 的术语(但现在我在 linux 中使用 CMake),所以在 Visual Studio 术语中,我有一个编译为动态库(.so 文件)的项目由几个头文件和源文件组成。这个 lib 中的主要对象是 Foo,所以 Foo 的头文件和实现在这个项目中。在另一个项目(与另一个 Cmake 的不同文件夹)中,我有一个引用该项目的测试(CMake 的“add_dependencies”和“target_link_libraries”),在这个测试中,我有来自问题的
main函数。 (在下一条评论中继续) -
所以我希望如果我更改 Foo 的实现,例如 Foo::Foo() 现在将打印“我不在 .so 文件中”,然后通过创建 @987654344 @ 这将被打印出来,但是当我使用
(*create_foo_func)(&f2);创建 f2 时,它不会打印这一行。不幸的是 f1 和 f2 都打印了这行,这意味着它们都创建了相同类型的对象(或至少使用相同的实现)
标签: c++ linux cmake shared-libraries dlopen