2017-04-20 12 views
2

私は、WebサイトをローカルデータベースにリンクするためにC#でWebサービスを開発しています。ローカルアプリケーションのSDKはCOMオブジェクトです。私はVBのコードの下に変換する方法で私の心を壊しています二日目は、C#と同等に(SDKプロトコルに与えられた):C#でIDispatchをキャストする方法

System.Type objType = System.Type.GetTypeFromProgID("PERCo_S20_SDK.ExchangeMain"); 
      dynamic comObject = System.Activator.CreateInstance(objType); 
      if (comObject.SetConnect("192.168.1.14", "211", "ADMIN", "") != 0) 
      { 
        //Could not connect to server! 
      } 
      XmlDocument dep_xml = new XmlDocument(); 
      XmlDeclaration dep_xml_decl = dep_xml.CreateXmlDeclaration("1.0", "UTF-8", "yes"); 
      XmlElement root = dep_xml.DocumentElement; 
      dep_xml.InsertBefore(dep_xml_decl, root); 
      XmlElement element = dep_xml.CreateElement(string.Empty, "documentrequest", string.Empty); 
      element.SetAttribute("type", "subdiv"); 
      dep_xml.AppendChild(element); 
      comObject.GetData(dep_xml as IDispatch); 
      comObject.Disconnect(); 

で:

XML_DOM := CreateOleObject('MSXML2.DOMDocument.3.0') as IXMLDOMDocumen 
GetData(XML_DOM as Idispatch) 

私はこれ試してみました

[ComImport, InterfaceType(ComInterfaceType.InterfaceIsIUnknown), Guid("00020400-0000-0000-C000-000000000046")] 
     private interface IDispatch 
     { 
      [PreserveSig] 
      int GetTypeInfoCount(out int Count); 

      [PreserveSig] 
      int GetTypeInfo 
      (
       [MarshalAs(UnmanagedType.U4)] int iTInfo, 
       [MarshalAs(UnmanagedType.U4)] int lcid, 
       out System.Runtime.InteropServices.ComTypes.ITypeInfo typeInfo 
      ); 

      [PreserveSig] 
      int GetIDsOfNames 
      (
       ref Guid riid, 
       [MarshalAs(UnmanagedType.LPArray, ArraySubType = UnmanagedType.LPWStr)] 
       string[] rgsNames, 
       int cNames, 
       int lcid, 
       [MarshalAs(UnmanagedType.LPArray)] int[] rgDispId 
      ); 

      [PreserveSig] 
      int Invoke 
      (
       int dispIdMember, 
       ref Guid riid, 
       uint lcid, 
       ushort wFlags, 
       ref System.Runtime.InteropServices.ComTypes.DISPPARAMS pDispParams, 
       out object pVarResult, 
       ref System.Runtime.InteropServices.ComTypes.EXCEPINFO pExcepInfo, 
       out UInt32 pArgErr 
      ); 
     } 

が、私はエラーを取得

An exception of type 'System.ArgumentException' occurred in System.Dynamic.dll but was not handled in user code 

Additional information: Could not convert argument 0 for call to GetData. 

私はどのようにC#でIDispatchをキャストする必要があります助けてください。

+1

明らかに.NET XmlDocumentクラスを使用していますが、管理されていない(MSXML2.DOMDocument.3.0)のフレーバではありません。 IDispatchに変換することはできません。プロジェクト>参照の追加> COMタブで「Microsoft XML、v3.0」を選択します。 –

+0

@HansPassant「Microsoft XML、v3.0」への参照が追加されました。渡すパラメータの部分は何ですか:GetData(XML_DOMをIdispatchとして)? –

+1

'new MSXML2.DOMDocument30()'を使用してオブジェクトを作成します。キャストは必要ありません。 –

答えて

1

An exception of type 'System.ArgumentException' occurred in System.Dynamic.dll but was not handled in user code

Additional information: Could not convert argument 0 for call to GetData.

あなたの問題はここにある:

XmlDocument dep_xml = ... 
comObject.GetData(dep_xml as IDispatch); // <------ BANG!! 

XmlDocumentは標準OLEオートメーション/ディスパッチタイプではありません。

  • int
  • float
  • char
  • BSTR
  • SAFEARRAY
  • etc

...またはオブジェクトが012を暴露:それはないです、XmlDocumentが実装していないCOMインターフェイス。 XmlDocumentには[ComVisible]が必要です。

オブジェクトは、あなただけの、その後、COM準拠できなかった場合:

comObject.SomethingOrOther(myComCompliantObject); 

...不要なキャストなし。

+0

回避策はありますか? IDispatchを実装するためにどのオブジェクトを使用する必要がありますか? –

+0

私が考えることができる唯一の回避策は、COMライブラリのソースにアクセスして、それをC++/CLIにすることができれば、古い 'オブジェクト'をCOMメソッドに渡すことができます。 'IUnknown'を既知の型の管理オブジェクトにキャストすることができます(実際にはキャストしていません)。私はこれを従来のコードで一度やらなければなりませんでした。明日コードフラグメントを投稿します – MickyD

+0

残念ながら私はCOMのソースにアクセスできない。 COMObject.GetType()。InvokeMember( "GetData" .....もしそうなら、どのように? –

関連する問題