COMインターフェイスのC#実装で構造体のパッキングサイズを指定することはできますか?COMインターフェイスのC#実装で構造体パッキングを指定する
(構造体が管理側にに定義されていますが、私の質問は、それが管理されていない側に定義されていたときについてですとは、管理側でを実装したときに、私はそれを行う方法を知っている。)
私はstruct型を定義するCOM型ライブラリと、それらの構造体の配列を返すインターフェイスメソッドがあります。私はC#サーバーとアンマネージC++サーバーを持っています。このサーバーは両方ともこのインターフェイスを実装しており、それを消費するC++クライアントです。 C++サーバーとC++クライアントは、構造体を32ビットのビルドでは4バイトに、64ビットのビルドでは8バイトにパックします。
しかし、プラットフォーム(x86、x64、AnyCPU)に関係なく、C#サーバーは常に4バイトにパックされます。これは正常ですか?オーバーライドできますか?
typedef [v1_enum] enum { blah... } HandlerPriority;
struct HandlerInfo { BSTR MessageName; HandlerPriority Priority; }
のVisual Studio C++とMIDLコンパイラはの/ Zp8デフォルトのパッキングを使用します。
構造体は次のようになります。 32ビットのビルドでは、構造体の両方のメンバーが4バイト幅であるため、パディングされません。 64ビットのビルドでは、文字列ポインタは8バイトで、列挙型は4なので、列挙型は埋め込まれます。当然ながら、これはC#クライアントが未実装のデータを送信するときに問題を引き起こします。
パディングを削除するために/ Zp4を指定することで問題を解決できますが、すべて問題なく動作しているようです。しかし、それが最善の解決策であるかどうかは疑問です。
パフォーマンス上の理由から、デフォルトのパッキングは/ Zp8と考えています。私が理解しているように、x64ではデフォルトでハードウェアがトラップし、整列例外を処理するので、少なくともクラッシュすることはありません。この特定の状況では、インタフェース機能はシステムの起動時にのみ呼び出されるため、パフォーマンス上の不利益は気にしません。私が気にしていたとしても、それをCOM/.NET interopのコストとして受け入れているかもしれません。しかし、私はそれが間違っているので少し不安です(C++の背景から来ています)。
一方、管理側のパッキングを変更することはできません。それと。
誰かから助言をいただけますか?
周りにたくさんの掘り下げが終わった後... .NET DLLは実際にはどんなサイズにパックされているようです。構造体定義を含むCOMタイプライブラリをラップするtlbimp生成RCWからパッキングサイズを取得します。 tlbimpを使って、もし私が/ platform:x64と言うなら、RCWは ".pack 8"と言っていますが、私が/ platform:agnosticと言うと ".pack 4"と言います。私はしたい/プラットフォーム:無関係な、私はちょうど両方のプラットフォームで8バイトにパックしたい。解決方法は、RCWを逆コンパイルし、生成されたソースコード内の.packディレクティブを変更し、再コンパイルすることです。 –