6

遅延バインディングCOMオブジェクトのc#実装を呼び出すアンマネージコードをエミュレートするためのテストコードを作成しています。以下のようにIDispatchタイプとして宣言されているインターフェースがあります。

 [Guid("2D570F11-4BD8-40e7-BF14-38772063AAF0")]
 [InterfaceType(ComInterfaceType.InterfaceIsDual)]
 public interface TestInterface
 {
     int Test();
 }

 [ClassInterface(ClassInterfaceType.AutoDual)]
 public class TestImpl : TestInterface 
 {
 ...
 }

以下のコードを使用してIDispatchのGetIDsOfNames関数を呼び出すと

  ..
  //code provided by Hans Passant
  Object so = Activator.CreateInstance(Type.GetTypeFromProgID("ProgID.Test"));
  string[] rgsNames = new string[1];
  int[] rgDispId = new int[1];
  rgsNames[0] = "Test";

  //the next line throws an exception
  IDispatch disp = (IDispatch)so;

IDispatchは次のように定義されます。

 //code provided by Hans Passant
 [ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")]
 private interface IDispatch {
     int GetTypeInfoCount();
     [return: MarshalAs(UnmanagedType.Interface)]
     ITypeInfo GetTypeInfo([In, MarshalAs(UnmanagedType.U4)] int iTInfo, [In, MarshalAs(UnmanagedType.U4)] int lcid);
     void GetIDsOfNames([In] ref Guid riid, [In, MarshalAs(UnmanagedType.LPArray)] string[] rgszNames, [In, MarshalAs(UnmanagedType.U4)] int cNames, [In, MarshalAs(UnmanagedType.U4)] int lcid, [Out, MarshalAs(UnmanagedType.LPArray)] int[] rgDispId);
  }

InvalidCastExceptionがスローされます。ac#インターフェースをIDispatchにキャストすることは可能ですか?

4

2 に答える 2

1

COMタイプのリフレクションを使用して、メソッドのリストを取得できるはずです。

Type comType = Type.GetTypeFromProgID("ProgID.Test");
MethodInfo[] methods = comType.GetMethods();
于 2011-11-09T18:41:05.993 に答える
1

アセンブリをregasmに登録する必要があり、COMからアクセスするクラスを[ComVisible]属性でマークする必要があります。また、tlbexp(生成するため)とtzippyを使用してタイプライブラリを生成して登録する必要がある場合もあります。

また、(Win32の観点から) "disp =(IDispatch)obj"は "disp = obj as IDispatch"と同じではありません-'as'演算子を使用すると、実際にオブジェクトのQueryInterfaceメソッドを呼び出して、要求されたインターフェイスへのポインターを取得します、オブジェクトをインターフェイスにキャストしようとする代わりに。

最後に、c#の「動的」タイプを使用すると、他の人がクラスにアクセスするために行っていることにおそらく近いでしょう。

于 2012-03-13T01:27:00.190 に答える