WCHAR array is not configured properly

I have a COM interface with the following method definition (IDL notation):

SCODE GetText( [in, out] ULONG* pcwcBuffer,
              [out, size_is(*pcwcBuffer)] WCHAR* awcBuffer );

      

Typelib routing is used for COM +, type library is registered, other interface methods work when called through COM +, but not this method.

The server side copies the array WCHAR to awcBuffer

and its length to pwcBuffer

, never a buffer overflow.

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;
}

      

When a client calls this method through COM +, the contents of the buffer are lost. In particular, only the first wide char is stored - if the server copies the wide character string "Sample", the client only receives the string "S". The return value for client size is S_OK, the length of the buffer returned to the client is exactly the same as the server copy.

I finally switched to BSTR to work around this issue, but really wondering why the whole construct in action isn't working.

What is the possible reason for the described behavior?

0


a source to share


3 answers


IIRC, the typelib marshaler ignores the size_is attribute - so only 1 char is marshaled.



+3


a source


J. The transmission is correct. For the typelib marshaller to work, the COM interface must be OLE Automation compatible. The typelib router is implemented in oleaut32.dll, so I assume there is a key in it.

[size_is] is a perfectly valid IDL and compiles to a valid typelib, but the typelib marshaler can only handle a subset of valid interfaces. This subset is commonly referred to as OLE Automation. As an aside, VB6 clients can only speak OLE Automation, so they won't be able to use your interface either.

Try to mark your interface with the [oleautomation] attribute in IDL. It should give you a warning or error message that can point you to more information on the matter.



In "normal" COM, you can create a proxy / stub DLL from your IDL to do the marshalling, but I'm afraid I don't remember if COM + would use your custom marshalling code, even if you bothered to build it.

Update: In Juval Lowy's book "COM and .NET Services" I found this expression: "... configured components cannot use interfaces that require custom marshaling." So my guess is that the interface will never work in COM +. If you can, rewrite to use BSTR.

+2


a source


A couple of questions:

  • Why don't you use BSTR

    ?
  • Do you have sources of the function GetText

    ?
  • What is the size of the buffer returned by the function?
0


a source







All Articles