c++ - 自动为使用 dlopen() 加载的类创建包装器

标签 c++ templates shared-libraries dlopen

我正在编写一个代理类,它使用 dlopen() 加载共享库,并将其成员函数转发到幕后加载的共享对象内的代理类实例的适当成员。

例如,共享对象有一个 Person 类:

class Person
{
    ...
    void setName(std::string name);
};

我添加了一个包装文件,其中包含 person.h header 并定义以下符号:

extern "C" {
    void Person_setName(void* instancePointer, std::string name);
}

此调用仅转发到作为第一个参数的 person 对象,extern "C" 以避免整个名称损坏问题。在客户端,我编写了一个具有相同成员的 Person 类,该类包含指向包装类的指针并转发所有调用。

现在出现一些问题:

  1. 是否有更好的方法来实例化和使用加载的共享对象中的类?我找到了一些其他可以在没有包装器的情况下运行的解决方案,但在 Usenet 上不鼓励使用,并且高度依赖于 GCC 及其版本以及未定义的行为,因此我决定反对该路线。
  2. 有没有办法自动创建这些包装器?它们都只是添加第一个参数,该参数是指向每个方法的实例的指针,并转发到真实的东西。必须有一些模板魔法才能做到这一点,不是吗?目前我正在使用一些宏来完成这项工作,但我对模板解决方案感兴趣。
  3. 也许有一些工具可以自动完成这样的事情,比如 SWIG?据我所知,SWIG 只是用于将 C++ 接口(interface)导出到高级语言。

最佳答案

is there a better way to instantiate and use a class from a loaded shared object?

如果您想安全并支持任何共享对象(即由任何编译器/标志等编译),那么不行:您必须通过 C ABI。

请记住,您也不应该在界面中使用 C++ 对象,例如就像您在 Person_setName 中传递的 std::string 一样。

is there a way to automate the creation of those wrappers? There has to be some template magic for that, no? Currently I'm using some macros for the job but I'd be interested in a template solution.

不,您不能即时创建成员函数(我们还没有反射、元类和类似的编译时功能)。

They are all just adding a first argument that is a pointer to an instance to each method and forward to the real thing.

当然,您可以创建一个可变参数模板,将参数转发给给定的 extern "C" 函数,但与简单地调用 C 函数相比,您并没有真正从中获得任何有用的东西。换句话说,不要这样做:要么创建适当的 C++ 类,要么让用户调用 C 函数。

Maybe there is some tool that can do such a thing automatically, like SWIG? As far as I've seen SWIG is just for exporting a C++ interface to high level languages.

我用过Clang's tooling support过去执行类似的任务作为预构建步骤,所以这确实是可能的!

关于c++ - 自动为使用 dlopen() 加载的类创建包装器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56932785/

相关文章:

c++ - 如何在 Linux 上使用 polkit 请求串口权限?

c++ - 如何为 lambda 创建唯一类型?

c++ - 在 Linux 上不使用非标准库的情况下使用 C++ 从 Web 下载文件

c++ - 当 .so 尝试使用主可执行文件中的类时,dlopen() 给出未解析的符号错误。为什么?

java - 如何为您编写的每个程序创建自己的 Android 开发库?

c++ - Delphi XE - 无法从系统菜单中删除项目

c++ - 为什么不能将 Q_OBJECT 与模板类一起使用?

C++ 模板的模板编译失败

c++ - 从模板抽象类继承

c++ - 来自 C 和 C++ 目标文件的共享库