有人可以解释这个.NET COM互操作性代码

时间:2010-07-16 06:51:50

标签: c# .net com

  • 我在IDL中有一个COM接口方法定义,如下所示:

    [id(8)]
    HRESULT GetBinData([in,out,size_is(dataLen)]BYTE data[], [in]LONG dataLen);
    

  • 它会自动映射到此.NET IL代码(请注意,数据上没有使用MarshallAs LPArray):

    .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/*23000001*/]
         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
    

  • 该代码在C#中查找:

    [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);
    

  • 现在我的问题不是如何做得更好(我知道)但是: (a)为什么我的代码完全适用? (b)是否存在此类代码可能无法工作的情况(例如,在调用GetBinData时内存在CLR内移动等)。
  • 1 个答案:

    答案 0 :(得分:0)

    垃圾收集不应该与您有关,因为您将对象 一旦将其传递给方法后自动固定(来源:MSDN):

      

    当运行时封送程序看到时   你的代码传递给本机代码a   对托管引用的引用   对象,它会自动固定   对象

    如果您的本机方法为稍后的异步工作保存了引用(指针),则必须手动固定它:

    byte[] b = new byte[1024];
    GCHandle pinHandle = GCHandle.Alloc(b, GCHandleType.Pinned);
    try
    {
       someObject.GetBinData(ref b[0], b.length);
    }
    finally
    {
       pinHandle.Free();
    }
    

    否则,没有理由不这样做。您在调用方法之前分配内存,CLR将您的对象固定,直到执行该方法,并且您的本机代码应注意考虑数组长度。