0

次のメソッド定義(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に切り替えましたが、有効な外観の構成全体が機能しない理由は非常に興味深いものです。

説明されている動作の考えられる理由は何ですか?

4

3 に答える 3

3

IIRC、typelibマーシャラーはsize_is属性を無視します。したがって、1文字のみがマーシャリングされます。

于 2009-05-13T12:43:32.613 に答える
2

J.合格は正しいです。typelibマーシャラーが機能するには、COMインターフェイスがOLEオートメーションと互換性がある必要があります。typelibマーシャラーはoleaut32.dllに実装されているので、名前に手がかりがあると思います。

[size_is]は完全に有効なIDLであり、有効なtypelibにコンパイルされますが、typelibマーシャラーは有効なインターフェイスのサブセットのみを処理できます。そのサブセットは通常、OLEオートメーションと呼ばれます。余談ですが、VB6クライアントはOLEオートメーションしか話せないため、インターフェイスを使用することもできません。

IDLの[oleautomation]属性でインターフェースをマークしてみてください。それはあなたに主題に関するより多くの情報をあなたに示すかもしれない警告またはエラーメッセージを与えるべきです。

「通常の」COMでは、IDLからプロキシ/スタブDLLを生成してマーシャリングを実行できますが、COM +がカスタムマーシャリングコードを使用するかどうかは、わざわざ作成したとしても覚えていません。

更新:JuvalLowyの著書「COMand.NET Component Services」で、次のステートメントを見つけました。「...構成されたコンポーネントは、カスタムマーシャリングを必要とするインターフェイスを使用できません」。したがって、インターフェイスはCOM+では機能しないと思います。可能であれば、代わりにBSTRを使用するように書き直してください。

于 2009-05-13T12:53:33.707 に答える
0

いくつかの質問:

  • なんで使ってないのBSTR
  • 関数のソースはありGetTextますか?
  • 関数によって返されるバッファのサイズはどれくらいですか?
于 2009-05-13T12:13:45.987 に答える