我正在尝试为C#委托返回值
实现自定义封送程序[return: MarshalAs(UnmanagedType.CustomMarshaler,MarshalType = "MyCustomMarshaler")]
public delegate MSyntax SyntaxCreator();
在C ++中,MSyntax类型是普通的C ++类。
在C#中,MSyntax类型是一个普通的C#类(不是结构),它有一个内部指针(使用IntPtr)到C ++类。
所以我写了像MarshalManagedToNative这样的方法:
public IntPtr MarshalManagedToNative(Object ManagedObj)
{
MSyntax msyntax = ManagedObj as MSyntax;
// GetNativeDataSize() returns what sizeof(MSyntax) returns in C++
IntPtr ptrBlock = Marshal.AllocCoTaskMem( GetNativeDataSize() );
unsafe
{
byte* ptrDest = (byte *)ptrBlock.ToPointer();
byte* ptrSource = (byte *)msyntax.GetInternalCPlusPlusPointer();
for( uint i = 0; i < GetNativeDataSize(); ++i )
{
*ptrDest = *ptrSource;
++ptrDest;
++ptrSource;
}
}
return ptrBlock;
}
正如您所看到的,它使用Marshal.AllocCoTaskMem分配足够的内存来保存C ++ MSyntax的新实例,然后将内部C ++ MSyntax的内容从ManagedObj复制到这个新实例。
它几乎可以工作。 在C ++中,此委托/回调函数的调用者执行以下操作:
MSyntax syntax = CallCallbackFunction();
在正常的C ++中执行此行时,C ++创建一个新的MSyntax实例,调用MSyntax的复制构造函数,传递对“CallCallbackFunction()”返回的MSyntax的引用,然后调用该引用的析构函数,因为它是一个中间体值(可能在堆栈上)。
现在在我的情况下,调用最终调用我的MarshalManagedToNative方法,返回时,相应地调用MSyntax的C ++拷贝构造函数并且工作正常。如果我调试它,我可以看到传递给复制构造函数的引用是我从MarshalManagedToNative方法返回的IntPtr,所以这很好。但最后MSyntax的析构函数被称为,但是“this”指针是错误的,所以它失败了...... “this”指针不是我从MarshalManagedToNative方法返回的IntPtr ...它可能是堆栈上的地址......难怪。
所以我想知道如何实现MarshalManagedToNative方法以使此代码正常工作? (顺便说一句,我在win64上,所以这是使用的快速调用约定。)
在浏览网页时,我发现编组人员对定制编组人员有一些特殊的期望。例如,如果您有这样的方法:
void foo( [in: MarshalAs(UnmanagedType.CustomMarshaler,MarshalType = "MyCustomMarshaler")] SomeClass * arg );
编组程序将从您的MarshalManagedToNative方法返回IntPtr并期望首先在此内存地址处找到一个整数,该整数表示整数后有多少SomeClass元素(因为SomeClass *指针参数可能是一个数组)。 / p>
你们知道这些文件记录在哪里吗?很抱歉,但我找不到它:-(
我希望找到一些特殊的信息来决定我应该如何实现MarshalManagedToNative方法。
由于