使用对象地址、方法地址和签名调用 C++ 成员函数
calling a C++ member function using the object address and the method address and signature
如何在知道对象地址和方法地址(及其签名)的情况下调用对象的方法:
auto x = (int(*)())(&A::get_state)
让对象 x
类型 void*
。
因此,使用 x
和 m
,void*
类型的 x
和 int(*)()
类型的 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
实现构建的)。
如何在知道对象地址和方法地址(及其签名)的情况下调用对象的方法:
auto x = (int(*)())(&A::get_state)
让对象 x
类型 void*
。
因此,使用 x
和 m
,void*
类型的 x
和 int(*)()
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
实现构建的)。