ATLからC#に一連の構造体(std:stringまたはbstrを含む)を渡すにはどうすればよいですか。 SAFEARRAY?変異体?
質問
C#から使用しているATL comオブジェクトがあります。現在、インターフェイスは次のように見えます。
interface ICHASCom : IDispatch{
[id(1), helpstring("method Start")] HRESULT Start([in] BSTR name, [out,retval] VARIANT_BOOL* result);
...
[id(4), helpstring("method GetCount")] HRESULT GetCount([out,retval] LONG* numPorts);
...
[id(7), helpstring("method EnableLogging")] HRESULT EnableLogging([in] VARIANT_BOOL enableLogging);
};
つまり、非常に単純なインターフェイスです。また、返送するイベントもいくつかあります。今、私はインターフェイスに何かを追加したいと思います。 ATLにはいくつかの結果があります。これは現在構造体であり、struct Report_line {string creationdate;のように見えます。文字列ID;文字列の概要; }; structのすべてのメンバーはstd :: stringです。 C#に戻るために必要なこれらの配列があります。これを行うための最良の方法は何ですか?
誰かが「ねえ、あなたはそのようなcomの上にstd :: stringを送ることはできません。もしそうなら、構造体をmodidfyに変える最良の方法は何ですか?そして、1)IDLを設定して、Safearraysを使用する必要がある場合、Safearraysを構造体で埋めるにはどうすればよいか(BSTRまたはSTD :: STRINGを使用して構造体)を渡すように設定します。
単純なタイプで使用することを除いて、私はcomに精通していません。
解決
ユーザー定義構造は、自動化インターフェイスと互換性がありません。おそらく、ネストされたアレイまたは2次元セーフアレイのBSTRSを作成できますが、より保守可能なソリューションは、3つのプロパティを備えた自動化オブジェクトとして構造を包み、列挙器を持つコレクションとして配列をラップすることです。
IDLも自動化も、構造体のバイトアラインメントを定義しません。したがって、COMサーバーがクライアントと異なるstructアラインメントを持っている場合、互換性の問題を抱える可能性があります。たとえば、VBには4バイトのアライメントがあり、Visual C ++の#importは8バイトのアライメントにデフォルトです。将来、スクリプトでインターフェイスを使用する可能性がわずかにある場合は、構造体の使用を避けてください。
提案された読書:
- "Don Box、Microsoft Systems Journal、1996年6月のIdispatchを通過する構造を渡す.
- *収集および列挙者のインターフェイスの設計原則
- *ATL内部:Chris Tavares、Kirk Fertitta Page 392によるATL 8との協力