Simon Fell > Its just code > COM / .NET Interop
Thursday, September 9, 2004
So I'm sure this is possible, I just can't work out the right set of incantations. I have a COM interface which represents a simple readable stream
[
object,
uuid(114BD3E3-983B-4509-8DD7-42DC36F4D262),
local,
helpstring("IStreamReader Interface"),
pointer_default(unique)
]
interface IStreamReader : IUnknown
{
HRESULT Read( void *pv, // Pointer to buffer into which the stream is read
ULONG cb, // Specifies the number of bytes to read
ULONG *pcbRead ); // Pointer to location that contains actual
// number of bytes read
HRESULT Reset() ; // resets the current position in the stream back to the begining.
} ;
No rocket science here, pass a buffer into the Read call and it'll populate some or all of it. Now, I'm trying to provide an implementation of this COM interface in C#, what I've got so far is
[ComImport, Guid("114BD3E3-983B-4509-8DD7-42DC36F4D262")]
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
public interface IStreamReader
{
[PreserveSig]
void Read ( [MarshalAs(UnmanagedType.LPArray, SizeParamIndex=1)] byte [] buffer,
uint cb,
out uint pcbRead ) ;
[PreserveSig]
void Reset ();
}
Now I can see my call into the c# code, it gets a right sized buffer, it drops data into the buffer and updates pcbRead, everything looks fine on the .NET side, step through back to the C++ code, and pcbRead is fine, but there's no data in the buffer, it didn't get marshalled back. This seems to be because the buffer is only marshalled as an [in], I tried adding a ref to the byte [] buffer, but now when my c++ code tries to call it i get a HRESULT of 0x80131535 which is MarshalDirectiveException.
Anyone know the trick for this one ?
Update : As this things always go, I worked it out 5 minutes later, ditching the ref and adding an [In,Out] to the byte [] parameter did the trick.