简体   繁体   English

C ++从void *转换为SomeClass *

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

I'm working on a C++ library that is going to be dynamic loaded (dlopen, dlsym...) in C++ and C programs as a plugin. 我正在开发一个C ++库,它将在C ++和C程序中作为插件动态加载(dlopen,dlsym ...)。

C++ programs will use a creator a destroyer functions from the library to call the constructor and destructor respectively. C ++程序将使用库中的驱动程序函数来分别调用构造函数和析构函数。 Something like this: 像这样的东西:

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

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

Problem is: It is not that type safe. 问题是:它不是那种类型安全的。 Is it possible to be type safe here? 在这里可以安全吗? ( static_cast , dynamic_cast , reinterpret_cast ...) static_castdynamic_castreinterpret_cast ......)

This is important, since I intend to create a C wrapper for every MyClass method. 这很重要,因为我打算为每个MyClass方法创建一个C包装器。 That would allow me to load this library into a C program (something like DBus C porting that may be used with C style or C++ style). 这将允许我将此库加载到C程序(类似于可以与C风格或C ++风格一起使用的DBus C移植)。 So I'd do something like this: 所以我会做这样的事情:

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

Please, keep in mind this is just a dummy example. 请记住,这只是一个虚拟的例子。

Thanks very much. 非常感谢。

Not really. 并不是的。 The whole point of going through a C interface is that you strip all dependence on any C++ ABI, so there's no way you can preserve type information through that in a "natural" fashion. 通过C接口的全部意义在于您消除了对任何C ++ ABI的依赖,因此您无法以“自然”的方式保存类型信息。

f it really matters to you, you could rig up some complicated metadata infrastructure to allow for some runtime tests, but you certainly won't get compile-time type-safety out of this. 如果你真的很重要,你可以安装一些复杂的元数据基础设施以允许一些运行时测试,但你肯定不会得到编译时类型安全性。

You could use a std::map<void*, MyClass*> . 您可以使用std::map<void*, MyClass*> Then if the pointer isn't recognized, you'll get a "no element found in map" type of error instead of undefined behavior. 然后,如果指针未被识别,您将获得“在地图中找不到元素”类型的错误而不是未定义的行为。

You might be able to get some measure of type safety by giving the C API pointers to C-style structs which in turn contain pointers to your C++ objects. 您可以通过向C样式结构提供C API指针来获得一些类型安全性,这些结构又包含指向C ++对象的指针。 Then you have more control over the pointers (provided C clients don't interfere inside the structs, which they most certainly shouldn't) and there's some type checking on the C side too. 然后你可以更好地控制指针(假设C客户端不会干扰结构内部,它们肯定不应该这样做)并且在C端也有一些类型检查。 Something like: 就像是:

struct MyClassHandle {
    void * ptr;
}

Then you have a pretty good idea that the ptr from inside a MyClassHandle will cast successfully to MyClass *. 然后你有一个很好的想法,来自MyClassHandle内部的ptr将成功转换为MyClass *。

But as Kerrek SB said, you can't get any kind of type safety when you're casting from void * - the information just isn't there. 但是正如Kerrek SB所说的那样,当你从虚空中进行投射时,你无法获得任何类型的安全性 - 信息就不存在了。

You might also consider using handles (not pointers - just ints). 您也可以考虑使用句柄(不是指针 - 只是整数)。 For example you can hold a global array or a map that matches an int to a pointer, and make all your functions accept only such handles and then use that global array or map to find the matching pointer. 例如,您可以保存全局数组或将int与指针匹配的映射,并使所有函数仅接受此类句柄,然后使用该全局数组或映射来查找匹配指针。 In the case of an array the handle would just be an index in the array. 对于数组,句柄只是数组中的索引。

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

相关问题 C ++转换为空 - C++ cast to void C ++模板错误:从&#39;void TestClass :: testMethod(T,std :: map)实例化[T = SomeClass] - C++ templates error: instantiated from 'void TestClass::testMethod(T, std::map) [with T = SomeClass] 使用C ++样式转换从Void *转换为TYPE *:static_cast或reinterpret_cast - Cast from Void* to TYPE* using C++ style cast: static_cast or reinterpret_cast 为什么Visual C ++会在C中警告从const void **到void *的隐式转换,而不是在C ++中? - Why does Visual C++ warn on implicit cast from const void ** to void * in C, but not in C++? C ++无效,从&#39;void *&#39;类型转换为&#39;double&#39;类型 - C++ invalid cast from type ‘void*’ to type ‘double’ C ++ static_cast从float **到void ** - C++ static_cast from float** to void** C++ 类型转换:将指针从 void 指针转换为 class 指针 - C++ typecast: cast a pointer from void pointer to class pointer 删除在C ++中从void转换的指针是否安全? - Is it safe to delete a pointer that was cast from void in C++? 不能伪造来自 c++ 的托管回调(不能通过 static_cast 从 'void (GenFlowcacheTests::*)(int)' 转换为 'void(*)(int)') - cannot fake a managed callback from c++ (cannot cast from 'void (GenFlowcacheTests::*)(int)' to 'void(*)(int)' via static_cast) 是否在 glVertexAttribPointer 调用合法的 C++ 中转换为 void*? - Is cast to void* in a glVertexAttribPointer call a legal C++?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM