2016-07-29 9 views
0

私はC++/CLIでCOMラッパーを作成しており、問題へのアプローチ方法に苦労しています。C++/CLIとC# "as"演算子を使用したCOMラッパー

public ref class MyWrapped { 
    NativeType* unManagedEl; 
public: 
    Object^ getSomeItem() { return unManagedEl->getSomeItem(); } 
    ... 
}; 

およびC++/CLI管理されていない側:

var item = myWrappedObj.getSomeItem() as AnotherItem; 

C++/CLIは、側面が管理されていないオブジェクトへのポインタを保持している管理:

C#の側から

、私はこのようなコードを呼ぶことにしますそして、*のは返しますIUnknownのを言うの仕事をさせない、

public class UnknownBase { 
    IUnknown* myEl; 
public: 
    UnknownBase(IUnknown* el) { myEl = el; } 
    ... 
}; 

public class NativeType { 
    COMType* myEl; 
public: 
    Object^ getSomeItem() { 
     IUnknown* el; myEl->getItemNative(&el); return UnknownBase(el); 
    } 
}; 

今UnknownBaseネイティブクラスに包まれたが上記の「AnotherItem」型(上記の最初のコードのセクション)をインターフェイスに追加して、UnknownBaseなどから派生したマネージ+アンマネージラッパーを作成することを考えていました。どのようにC#の "as"演算子に対応するコードがありますか? MSDNから私はdynamic_castが "as"のために呼び出される対応する演算子だと理解していますが、IUnknownポインタをラップしたので、dynamic_castだけに依存することはできません。私は、クラスの型キャスト演算子をdynamic_cast(別の型キャスト演算子で型の等価性を手動でチェックできるように)で使用されるかどうかを調べようとしましたが、そうではないと思いますか?

マーシャリングされた+ tlbimp'edインターフェイスを使用するC#側の巨大なコードベースを使用していますので、インターフェイスをまったく同じに保つようにしています(「暗い側から」&バグを置き換えます)-marshalled私はデュアルラッパー(実際には、より多くの魔法を行うために別の名前空間など)を考え出しました。

+0

ラッパーが多すぎるため、このピクルスに入ったことがあります。 COMTypeはすでに完全に優れた型ですが、型なしのクラスでラップすると無用になりました。ラッパーを追加することで、もう一度ラップすることができます。これで、COMTypeを正しい方法で複製する必要があります。しかし、ラッパーを取り除く方がはるかに良い方法です。最低限、UnknownBaseを削除してください。これはまったく役に立ちますか?C#はすでに何の助けもなくCOMTypeを使用しています。 –

+0

私は恐れているCOMTypeはidl /ヘッダーからです、C#はそれを見ることができません。 – MattAPiroglu

+0

IDLの主な用途は、Tlbimpできるタイプライブラリを生成することです。もちろん、.hも生成できます。/tlbオプションを付けてmidl.exeを実行すると、実際に死んでいることを確認することができます。 UnknownBaseを終了し、少なくとも.hファイルはあなたに既知のベースを与えます。 –

答えて

0

私はIUnknown型が何であるかを知る必要があり、対応する管理型(refクラス)を見つけ出す必要があることを認識しました。私は上記の質問のコードを簡略化しましたが、通常は以下のコードに似ています(int型は正しい型を参照しています)。上記の例のコードに誤りがあると、質問に答えることが難しくなっている可能性があります。

また、アンマネージクラスとオブジェクトとの間の変換などはありません^ので、UnknownBase(el)を作成しようとするとうまくいきません。

public class NativeType { 
    COMType* myEl; 
public: 
    Object^ getSomeItem(int id) { 
     IUnknown* el; 
     myEl->getItemNative(id, &el); 
     switch(id) { 
      case 1: return gcnew AnotherItem(el); 
      case 2: return gcnew ... 
     } 
    } 
}; 

すぐにテストします。

関連する問題