0

クライアントからさまざまな型の値を送信する COM オブジェクトの COM ラッパーを作成しており、Map 内のこれらの型を実際の C++ 型 (VT_BSTR から wstring など) にマップしたいと考えています。

すべての COM Variant 型の列挙を定義し、マップを使用してその列挙型をキーとして、取得した値を含む実際の型を使用することを考えていましたが、グローバル型が見つからないように見えるという問題に直面していますマップに配置するために渡された文字列または double などにキャストできるマップに配置します。

おそらく、これを行う方法についての私の考えは完全に間違っています。アドバイスをお願いします。

私は 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 ステートメントが必要になる可能性があります。より良い方法があるかどうかはわかりません。

4

3 に答える 3

1

あなたが何をしようとしているのかわからない、それは確かに間違っているように聞こえます。クライアントから取得したVARIANTは、処理方法を知っているタイプに変換する必要があります。これは簡単です。VariantToXxxx()関数を呼び出すだけです。たとえば、文字列を取得する場合は、VariantToString()を使用します。

これを簡単にするいくつかのC++ラッパークラスがすでに利用可能です。_variant_t、CComVariant、COleVariant。それらはすべて同じことをしますが、#includeファイルが異なるだけです。_variant_tは、MFCまたはATLのどちらにも縛られないため、優れたものです。すでに使用している場合を除きます。それらのChangeType()メソッドは変換を行います。メモリ管理は自動です。

于 2010-09-01T14:48:44.037 に答える
0

_variant_tを知っていますか? 車輪の再発明をしているかもしれません。関連するすべてのコンストラクターとオーバーロードされた割り当てがあります。つまり、期待どおり_variant_t var = 0.0に動作します ( VT_R8)

于 2010-09-01T14:50:36.127 に答える
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);

このようにして、Variant から 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

この種の変換にマップと大量の if を使用することを主張する場合は、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を検討する価値があるかもしれません。

于 2010-09-01T14:17:25.070 に答える