Can someone explain this .NET COM interoperability code
[id(8)]
HRESULT GetBinData([in,out,size_is(dataLen)]BYTE data[], [in]LONG dataLen);
.method /*06000021*/ public hidebysig newslot virtual
instance void GetBinData([in][out] uint8& Data,
[in] int32 dataLen) runtime managed internalcall
// SIG: 20 02 01 10 05 08
{
.custom /*0C000052:0A000009*/ instance void
[mscorlib/*230000开发者_运维百科01*/]
System.Runtime.InteropServices.DispIdAttribute/*0100000F*/::.ctor(int32)
/* 0A000009 */ = ( 01 00 08 00 00 00 00 00 )
.override test.ISomething/*02000002*/::GetBinData/*02000002::06000008*/
} // end of method SomethingClass::GetBinData
[MethodImpl(MethodImplOptions.InternalCall,
MethodCodeType=MethodCodeType.Runtime), DispId(8)]
public virtual extern void GetBinData
([In, Out] ref byte Data, [In] int dataLen);
byte[] b = new byte[1024];
someObject.GetBinData(ref b[0], b.Length);
Garbage collection should not concern you, since you object is pinned automatically as soon as you pass it to the method (source: MSDN):
When the runtime marshaler sees that your code is passing to native code a reference to a managed reference object, it automatically pins the object.
In case that your native method saves the reference (pointer) for some later async work, you must pin it manually:
byte[] b = new byte[1024];
GCHandle pinHandle = GCHandle.Alloc(b, GCHandleType.Pinned);
try
{
someObject.GetBinData(ref b[0], b.length);
}
finally
{
pinHandle.Free();
}
Otherwise, there is no reason why it shouldn't work. You are allocating the memory before calling the method, CLR pins your object until the method is executed, and your native code should take care that array length is taken into account.
精彩评论