Groups | Blog | Home
all groups > dotnet interop > january 2007 >

dotnet interop : Returning pointer to array from C++ COM component to C#



tony.towers NO[at]SPAM gmail.com
1/16/2007 10:00:41 AM
I need to use a third party COM component. One of the methods has
the idl signature:-

HRESULT CalculateHash([in]BYTE* pDataBuffer, [in]long nDataBufferSize,
[out, retval] BYTE* pHashResult);

Both pDataBuffer and pHashResult are pointers to BYTE arrays, the size
of pDataBuffer is governed by nDataBufferSize; pHashResult has a fixed
size.

When I use tlbimp to create a C# wrapper library, the method signature
resulting is:-

byte CalculateHash(ref byte pDataBuffer, int nDataBufferSize);

Given a byte array byteData, I am hoping that "ref byteData[0]" can be
marshalled successfully for the parameter, but I am stumped as to how
to access the return value.

Any ideas?

Thanks in advance,

--
Tony Towers
Mattias Sjögren
1/16/2007 9:02:56 PM
Tony,

[quoted text, click to view]

If the method returns a byte array, the type of pHashResult should be
BYTE**.


[quoted text, click to view]

You'd probably get away with it, but it's not correct. A better way to
do it is described here

http://msdn2.microsoft.com/en-us/library/ek1fb3c6.aspx


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
tony.towers NO[at]SPAM gmail.com
1/17/2007 5:22:06 AM
Hi Mattias,

[quoted text, click to view]

Oh, I agree. Unfortunately it's a third-party component over which I
have no control.

[quoted text, click to view]

The "Preserve Signature" section looks like it could be a solution to
the problem, thank-you.

--=20
Tony Towers
Michael Shishkin
1/17/2007 5:23:35 PM
[quoted text, click to view]

Try

uint CalculateHash(
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1,
SizeParamIndex=1), In]
byte[] pDataBuffer,
int nDataBufferSize,
[MarshalAs(UnmanagedType.LPArray, ArraySubType=UnmanagedType.I1,
SizeConst=<int>, In, Out]
byte[] pHashResult);

replace "<int>" part in SizeConst attribute with real value of array
size. pHashResult better be preallocated before call. You might still
tony.towers NO[at]SPAM gmail.com
1/18/2007 3:09:09 AM

[quoted text, click to view]

I'm afraid I don't understand - this declaration should go into the IL
file
before recompiling the wrapper library?

--
Tony Towers
Michael Shishkin
1/18/2007 10:51:44 AM
[quoted text, click to view]

This would be C# wrapper definition for COM method. If you know COM
class GUID, it will not be necessary to compile wrapper library, you can
define your wrapper interfaces for COM interfaces you want to use in
your C# code. For example:

[ComVisible(false),
ComImport,
InterfaceType(ComInterfaceType.InterfaceIsIUnknown),
Guid("E561901F-03A5-4afe-86D0-72BAEECE7004")]
public interface IVssProviderNotifications
{
[PreserveSig()]
uint OnLoad([MarshalAs(UnmanagedType.IUnknown)] object pCallback);

[PreserveSig()]
uint OnUnload(int bForceUnload);
}

the rest of the code (how to use your interfaces, create and instantiate
COM objects) you can find here:

http://www.codeguru.com/csharp/csharp/cs_misc/com/article.php/c9065__2

AddThis Social Bookmark Button