使用映射将 COM VARIANT 类型映射到实际类型
我正在为 COM 对象编写一个 COM 包装器,该对象从客户端发送不同类型的值,并希望将 Map 中的这些类型映射到其实际的 C++ 类型,例如 VT_BSTR 到 wstring 等。
我正在考虑定义一个枚举的所有 COM 变体类型,然后使用映射将该枚举作为键和包含检索到的值的实际类型,但是我遇到了一个问题,即我似乎无法找到要放入我的映射中的全局类型可以转换为字符串或双精度数或交给我放置在地图中的任何内容。
也许我的想法是完全错误的,请指教?
我正在考虑一个 void 指针,但是编译器似乎不喜欢我的强制转换:(
示例)
enum Type
{
VT_INTEGER=0,
VT_DBL=1
};
map<Type, void*> typemap;
typedef pair<Type, void*> m_typepair;
typemap.insert( m_typepair(VT_INTEGER, 0));
typemap.insert( m_typepair(VT_DBL, (double)2.5)); // it does not like this cast
map<Type, void*>::iterator m_typeiter;
迭代此映射可能需要内部的 switch 语句来找到正确的类型,我不确定是否有更好的方法?
I am writing a COM wrapper for a COM object that sends different types of values from a client and want to map these types in a Map to their actual C++ type, such as VT_BSTR to a wstring, etc.
I was thinking of defining an enumuration of all COM Variant types and then using a map to have that Enum as the key and the actual type containing the retrieved value, however I'm running into the issue that I cannot seem to find a global type to put in my map that I can cast to a string or double or whatever is handed to me to place in the map.
Perhaps my thinking of how to do this is entirely wrong, please advice?
I was thinking of a void pointer, however it seems the compiler doesn't like my casts:
(example)
enum Type
{
VT_INTEGER=0,
VT_DBL=1
};
map<Type, void*> typemap;
typedef pair<Type, void*> m_typepair;
typemap.insert( m_typepair(VT_INTEGER, 0));
typemap.insert( m_typepair(VT_DBL, (double)2.5)); // it does not like this cast
map<Type, void*>::iterator m_typeiter;
Iterating this map would probably need a switch statement inside to find the right type, I'm not sure if there is a better way?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
您知道 _variant_t 吗?您可能正在重新发明轮子。它具有所有相关的构造函数和重载赋值。即
_variant_t var = 0.0
按预期工作 (VT_R8
)Are you aware of _variant_t ? You might be reinventing the wheel. It has all the relevant constrcutors and overloaded assignment. I.e.
_variant_t var = 0.0
works as expected (VT_R8
)我通常使用模板专门化来完成此类任务。我有一个模板函数,可以从变体类型转换为 C++ 类型,如下所示:
通过这种方式,您可以实现从变体类型到 C++ 类型的常量时间转换。另请注意,默认模板化函数没有主体 - 如果有人尝试对非专用类型使用转换,则会导致链接器错误(在大多数编译器上)。
类似地,您可以进行从 C++ 类型到 Variant 的转换:
如果您坚持使用映射和大量 if 进行此类转换,您可以使用 void* 指针,只需使用指向类型:
如果您对上述任何解决方案都不满意,boost::any 可能值得一看。
I usually use template specialization for this kind of tasks. I have a template function that converts from a variant type to a C++ type that looks like this:
This way you get a constant-time conversion from a Variant to a C++ type. Also note that the default templated function has no body - it will cause a linker error (on most compilers) if someone tries to use a conversion for an unspecialized type.
Similarly you can do the conversion from a C++ type to a Variant:
If you insist on using a map and tons of ifs for this kind of conversion, you can use your void* pointer, you just have to initialize it with a pointer to the type:
If you aren't satisfied with any of the above solutions, boost::any might be worth looking at.
不确定你想做什么,这听起来肯定是错误的。您从客户端获得的 VARIANT 需要转换为您知道如何处理的类型。这很容易做到,只需调用 VariantToXxxx() 函数即可。例如,如果您想获取字符串,请使用 VariantToString()。
已经有几个可用的 C++ 包装类使这变得更容易。 _variant_t、CComVariant、COleVariant。它们都做同样的事情,只是不同的 #include 文件。 _variant_t 是一个很好的选择,因为它不会将您束缚在 MFC 或 ATL 中。除非您已经在使用它们。他们的 ChangeType() 方法进行转换。内存管理是自动的。
Not sure what you're trying to do, it certainly sounds wrong. A VARIANT you get from a client needs to be converted to the type that you know how to deal with. That's easy to do, just call the VariantToXxxx() function. For example, use VariantToString() if you want to get a string.
There are several C++ wrapper classes already available that make this easier. _variant_t, CComVariant, COleVariant. They all do the same thing, just different #include files. _variant_t is a good one because it doesn't tie you into either MFC or ATL. Unless you are already using them. Their ChangeType() method makes the conversion. Memory management is automatic.