使用对象地址、方法地址和签名调用 C++ 成员函数

calling a C++ member function using the object address and the method address and signature

如何在知道对象地址和方法地址(及其签名)的情况下调用对象的方法:

auto x = (int(*)())(&A::get_state)

让对象 x 类型 void*

因此,使用 xmvoid* 类型的 xint(*)()

类型的 m

由于问题不太明确,我只是盲目猜测你想做什么,并简要说明如何做。


通常,使用 shared/dynamic 库的插件机制被实现,这样你就有了一个接口。

class IPlugin
{
    virtual int doSomething() = 0;
};

接下来,您在您的库中实现此接口,此外,还提供一个 C 函数来创建实现的实例 class(C 函数,因为它们没有名称损坏)。

class MyPlugin : public IPlugin
{
    int doSomething() override { /* ... */ }
};

extern "C" 
{ 
    IPlugin* createPlugin() 
    { 
        return new MyPlugin{}; 
    }
}

现在,在您的应用中,您使用 dlopen(或 Windows 上的 LoadLibrary)加载库,并使用 [=18] 获取 createPlugin 函数的地址=](或GetProcAddress):

void* addr = dlsym(handle, "createPlugin");

然后,将其转换为实际类型,这在所有库中都是等效的:

auto createPlugin = reinterpret_cast<IPlugin*(*)()>(addr);

通过调用 createPlugin,您现在可以创建具体实现的实例并通过界面访问它。不需要获取任何额外的方法,因为 virtual 成员函数可以直接跨库边界调用(因为 vtable)。

IPlugin* plugin = createPlugin();
int result = plugin->doSomething();

当然,同样适用于带参数和不同 return 类型的函数。但是,您应该导出另一个 C 函数以再次销毁对象实例。 delete 应始终由创建对象的库调用(因为库可能是使用与可执行文件不同的 new 实现构建的)。