WCHAR 配列が適切にマーシャリングされていない
-
21-08-2019 - |
質問
次のメソッド定義 (IDL 表記) を持つ COM インターフェースがあります。
SCODE GetText( [in, out] ULONG* pcwcBuffer,
[out, size_is(*pcwcBuffer)] WCHAR* awcBuffer );
Typelib マーシャリングは COM+ に使用され、タイプ ライブラリは登録されます。インターフェイスの他のメソッドは COM+ 経由で呼び出された場合に問題なく動作しますが、このメソッドは動作しません。
サーバー側は、WCHAR の配列を awcBuffer
そしてその長さは pwcBuffer
, 、バッファ オーバーランは決して発生しません。
static const wchar_t* Text = L"Sample";
STDMETHODIMP CImpl::GetText( ULONG* bufferLength, WCHAR* buffer )
{
const int length = wcslen( Text );
*bufferLength = length;
memcpy( buffer, Text, length * sizeof( WCHAR ) );
return S_OK;
}
クライアントが COM+ 経由でこのメソッドを呼び出すと、バッファの内容が失われます。具体的には、最初のワイド文字のみが保存されます。サーバーが「サンプル」ワイド文字列をコピーした場合、クライアントは「S」文字列のみを受け取ります。クライアント サイズの戻り値は S_OK で、クライアントに返されるバッファ長はサーバーがコピーしたものとまったく同じです。
この問題を回避するために最終的に BSTR に切り替えましたが、有効に見える構成全体がなぜ機能しないのかは非常に興味深いです。
説明されている動作の考えられる理由は何ですか?
解決
IIRCは、タイプライブラリのマーシャラーはsize_is属性は無視され - したがって、1つだけcharがマーシャリングされた
。他のヒント
J。引き渡しは正しいです。タイプライブラリのマーシャラーが機能するためには、COMインターフェイスは、OLEオートメーションの互換性がなければなりません。タイプライブラリのマーシャラーがのOleaut32.dllに実装されているので、私は名前に手がかりがあると思います。
は、[size_is] IDL完全に有効であり、有効なタイプライブラリにコンパイルが、タイプライブラリマーシャラは、唯一の有効なインターフェースのサブセットを扱うことができます。そのサブセットは、通常、OLEオートメーションと呼ばれています。余談として、VB6のクライアントのみがOLEオートメーションを話すことができるので、彼らはどちらか自分のインターフェイスを消費することができません。
あなたのIDLで[oleautomation]属性を使用してインタフェースをマークしてください。それはあなたの主題についての詳細をご指している可能性があります警告またはエラーメッセージを与える必要があります。
「通常の」COMでは、マーシャリングを行うには、あなたのIDLから、プロキシ/スタブDLLを生成することがありましたが、私はCOM +が、あなたがそれを構築するためにわざわざ場合でも、カスタムマーシャリングコードを使用するかどうか覚えていません怖いですます。
更新:ジュバル・ロウィの著書「COMおよび.NETコンポーネントサービス」で、私はこの文が見つかりました:「を...構成されたコンポーネントは、カスタムをマーシャリング必要とのインターフェイスを使用することはできません」。だから私は、そのインターフェイスがCOM +に働くことはありませんね。あなたができる場合は、代わりにBSTRを使用するように再書き込みます。
いくつかの質問:
- なぜ使わないのですか
BSTR
? - のソースはありますか
GetText
関数? - 関数によって返されるバッファのサイズはどれくらいですか?