繁体   English   中英

C ++从void *转换为SomeClass *

[英]C++ cast from void* to SomeClass*

我正在开发一个C ++库,它将在C ++和C程序中作为插件动态加载(dlopen,dlsym ...)。

C ++程序将使用库中的驱动程序函数来分别调用构造函数和析构函数。 像这样的东西:

void *creator(void *instance) {
    return new MyClass();
}

void destroyer(void *instance) {
    MyClass *_instance = static_cast<MyClass*>(instance);
    delete _instance;
}

问题是:它不是那种类型安全的。 在这里可以安全吗? static_castdynamic_castreinterpret_cast ......)

这很重要,因为我打算为每个MyClass方法创建一个C包装器。 这将允许我将此库加载到C程序(类似于可以与C风格或C ++风格一起使用的DBus C移植)。 所以我会做这样的事情:

int MyClassAddInts(void *instance, int a, int b) {
    MyClass *_instance = static_cast<MyClass*>(instance);
    return _instance->addInts(a, b);
}

请记住,这只是一个虚拟的例子。

非常感谢。

并不是的。 通过C接口的全部意义在于您消除了对任何C ++ ABI的依赖,因此您无法以“自然”的方式保存类型信息。

如果你真的很重要,你可以安装一些复杂的元数据基础设施以允许一些运行时测试,但你肯定不会得到编译时类型安全性。

您可以使用std::map<void*, MyClass*> 然后,如果指针未被识别,您将获得“在地图中找不到元素”类型的错误而不是未定义的行为。

您可以通过向C样式结构提供C API指针来获得一些类型安全性,这些结构又包含指向C ++对象的指针。 然后你可以更好地控制指针(假设C客户端不会干扰结构内部,它们肯定不应该这样做)并且在C端也有一些类型检查。 就像是:

struct MyClassHandle {
    void * ptr;
}

然后你有一个很好的想法,来自MyClassHandle内部的ptr将成功转换为MyClass *。

但是正如Kerrek SB所说的那样,当你从虚空中进行投射时,你无法获得任何类型的安全性 - 信息就不存在了。

您也可以考虑使用句柄(不是指针 - 只是整数)。 例如,您可以保存全局数组或将int与指针匹配的映射,并使所有函数仅接受此类句柄,然后使用该全局数组或映射来查找匹配指针。 对于数组,句柄只是数组中的索引。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM