C++动态链接库和void指针
C++ dynamically linked library and void pointer
我处于以下情况:我正在编写一个必须动态加载 C++ 库的 C++ 程序(即通过 dlopen
和 Linux 和 LoadLibrary
中的朋友和 Windows 中的朋友)。这可以通过创建 C 接口来完成。
现在,在程序和库中我管理一些 object,其中有一些指定的模板成员和一些方法:
struct MyObject {
std::vector<int> _vec;
//...
void do_something();
};
现在,如果库是静态加载的,我会编写一个库函数,例如
void some_function(MyObject& o);
但由于它是动态加载的,所以我需要一些其他签名。我在想以下内容:一个常见的 header like
//interface.hpp
extern "C" {
void ob_w(void*);
}
struct MyObject {
//...
}
然后,图书馆那边
//lib.cpp
#include "interface.hpp"
void ob_w(void* ptr)
{
MyObject* p = (MyObject*)ptr;
p->do_something();
}
并且,对于主程序
//main.cpp
#include "interface.hpp"
int main()
{
void* handle = nullptr;
void (*fptr)(void*);
handle = dlopen(...)
fptr = dlsym(...)
MyObject foo;
fptr((void*)&foo);
//...
}
环顾四周,我发现了其他类似的问题,但在所有这些问题中,库都是用 C 编写的,因此采用了不同的解决方案。这里库和程序都是用 C++ 编写的,void 指针只是为了避免一些适配器。 我想知道我的方法是否正确(我在linux机器上试过,似乎给出了正确的结果)和安全.如果不是,我如何在不引入任何开销的情况下传递 object 的指针(例如某些适配器)?
将我的评论提升为答案:如果您愿意使用 C++,则绝对不需要更改函数的签名以使其与动态链接一起使用。即以下作品:
extern "C" void some_function(MyObject& o) {
o.do_something();
}
然后你可以得到一个 main.cpp
如下(片段):
void* lib = dlopen("myobject.so", RTLD_LAZY);
if (not lib) fail_spectacularly();
void (*some_function)(MyObject&) = reinterpret_cast<decltype(some_function)>(dlsym(lib, "some_function"));
if (not some_function) fail_spectacularly();
MyObject obj = whatever;
some_function(obj);
我处于以下情况:我正在编写一个必须动态加载 C++ 库的 C++ 程序(即通过 dlopen
和 Linux 和 LoadLibrary
中的朋友和 Windows 中的朋友)。这可以通过创建 C 接口来完成。
现在,在程序和库中我管理一些 object,其中有一些指定的模板成员和一些方法:
struct MyObject {
std::vector<int> _vec;
//...
void do_something();
};
现在,如果库是静态加载的,我会编写一个库函数,例如
void some_function(MyObject& o);
但由于它是动态加载的,所以我需要一些其他签名。我在想以下内容:一个常见的 header like
//interface.hpp
extern "C" {
void ob_w(void*);
}
struct MyObject {
//...
}
然后,图书馆那边
//lib.cpp
#include "interface.hpp"
void ob_w(void* ptr)
{
MyObject* p = (MyObject*)ptr;
p->do_something();
}
并且,对于主程序
//main.cpp
#include "interface.hpp"
int main()
{
void* handle = nullptr;
void (*fptr)(void*);
handle = dlopen(...)
fptr = dlsym(...)
MyObject foo;
fptr((void*)&foo);
//...
}
环顾四周,我发现了其他类似的问题,但在所有这些问题中,库都是用 C 编写的,因此采用了不同的解决方案。这里库和程序都是用 C++ 编写的,void 指针只是为了避免一些适配器。 我想知道我的方法是否正确(我在linux机器上试过,似乎给出了正确的结果)和安全.如果不是,我如何在不引入任何开销的情况下传递 object 的指针(例如某些适配器)?
将我的评论提升为答案:如果您愿意使用 C++,则绝对不需要更改函数的签名以使其与动态链接一起使用。即以下作品:
extern "C" void some_function(MyObject& o) {
o.do_something();
}
然后你可以得到一个 main.cpp
如下(片段):
void* lib = dlopen("myobject.so", RTLD_LAZY);
if (not lib) fail_spectacularly();
void (*some_function)(MyObject&) = reinterpret_cast<decltype(some_function)>(dlsym(lib, "some_function"));
if (not some_function) fail_spectacularly();
MyObject obj = whatever;
some_function(obj);