COMインターフェイスのC#実装で構造体パッキングサイズを指定することは可能ですか?
(構造体が管理側で定義されている場合の方法は知っていますが、私の質問は、構造体が非管理側で定義され、管理側で実装されている場合についてです。)
構造体型を定義するCOM型ライブラリと、それらの構造体の配列を返すインターフェイスメソッドがあります。このインターフェイスを実装するC#サーバーとアンマネージC ++サーバー、およびそれを使用するC++クライアントがあります。C++サーバーとC++クライアントはどちらも、構造体を32ビットビルドでは4バイトに、64ビットビルドでは8バイトにパックします。
ただし、C#サーバーは、プラットフォーム(x86、x64、AnyCPU)に関係なく、常に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相互運用のコストとしてそれを受け入れるかもしれません。しかし、私はそれが間違っていると感じるので少し不安です(C ++のバックグラウンドから来ていると思います)。
逆に、管理側のパッキングを変更することが単純に不可能な場合は、私はそれを使用します。
誰かアドバイスをいただけますか?