2010-09-01 222 views
0

我正在为COM对象编写COM包装器,该对象从客户端发送不同类型的值,并且希望将这些类型映射到它们的实际C++类型,例如VT_BSTR到一个wstring等使用映射将COM VARIANT类型映射到实际类型

我想定义一个COM Variant类型的枚举,然后使用一个映射将该枚举作为键和包含检索值的实际类型,但是我遇到了问题,我似乎无法找到一个全球性的类型放在我的地图上,我可以投到一个字符串或双或任何交给我放在地图上。

也许我对如何做到这一点的想法是完全错误的,请指教?

我在想一个空指针的,但它似乎编译器不喜欢我的石膏:

(例如)

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语句中找到正确的类型,我不确定是否有更好的方法?

回答

0

我通常对这类任务使用模板专业化。我有一个模板功能,从一个变量类型转换为C++类,看起来像这样:

template <typename T> 
T variantToCpp(const Variant&); 

template <> 
int variantToCpp<int>(const Variant& v) 
{ 
    // Check that v really contains an int, if not, you can silently fail or throw an exception 
    // Get and return the int 
} 

template <> 
std::wstring variantToCpp<std::wstring>(const Variant& v) 
{ 
    // Check that v really contains a string, if not, you can silently fail or throw an exception 
    // Get and return the string 
} 

// etc. for each C++ type 

// Usage 
int i = variantToCpp<int>(someVariantIGotViaCOM); 

这样,你从一个变到C++类型的恒定时间转换。还要注意,默认的模板函数没有内容 - 如果有人试图对非特化类型使用转换,它会导致链接器错误(在大多数编译器上)。

同样可以做到从C++类型转换的Variant:

template <typename T> 
Variant cppToVariant(T); 

template <> 
Variant cppToVariant<int>(int val) 
{ 
    // Convert to variant and return it 
} 

// etc. for each type 

// Usage: 
int i = 10; 
Variant var = cppToVariant(i); // You don't even need to explicitly specify the type here, the compiler deduces it 

如果你坚持使用IFS的地图和吨这种转换,你可以用你的void *指针你只是有一个指针类型初始化:

int *myInteger = new int; *myInteger = 42; 
double *myDouble = new double; *myDouble = 42; 
typemap.insert(m_typepair(VT_INTEGER, myInteger)); 
typemap.insert(m_typepair(VT_DBL, myDouble)); 
// Don't forget to free them when you clear the map 

如果你不满意任何上述溶液中,boost::any可能是值得考虑的。

1

不知道你要做什么,它肯定听起来不对。您从客户端获得的VARIANT需要转换为您知道如何处理的类型。这很容易,只需调用VariantToXxxx()函数即可。例如,如果要获取字符串,请使用VariantToString()。

有几个C++包装类已经可用,使这更容易。 _variant_t,CComVariant,COleVariant。他们都做同样的事情,只是不同的#include文件。 _variant_t是一个很好的选择,因为它不会将您与MFC或ATL绑定。除非你已经在使用它们。他们的ChangeType()方法进行转换。内存管理是自动的。

0

您是否知道_variant_t?你可能正在重新发明轮子。它有所有相关的constrcutors和重载的任务。即_variant_t var = 0.0按预期工作(VT_R8