从原生到托管执行自定义编组(ICustomMarshaler)时如何正确释放内存?

时间:2014-06-02 09:16:50

标签: c# marshalling unmarshalling

我的主要应用程序是在C#中,我现在正在尝试编写一个DLL(用于输入输出),该DLL应该是可移植的(在C或C ++中用于Windows和Linux)并且可以从其他C ++应用程序和来自我的主要C#app。

虽然在我的DLL中我使用C ++来让我的生活更轻松,但我使用C风格的方法来实现界面,即我有外部" C"我的标题中有{/ * methods * /}。我认为这比使用C ++ / CLI包装更好(希望这是正确的选择,因为我已经足够了,但我很高兴听到你对这个问题的建议)。

现在在我的本机DLL中我有结构,其中包含其他几个结构和数组。我通过以下示例简化(很多):

typedef struct AStructNative{
    size_t     length,
    void*      bstructs;
}AStructNative;

typedef struct BStructNative{
    int16_t    a;
    int16_t    b;
}BStructNative;

与C#同行:

public class AStruct { BStruct[]  array; }
public struct BStruct { short a; short b; }

我使用ICustomMarshaler并且AStruct(1)可以传递给本机DLL(写入时)或(2)可以从DLL获取(回读时)。我认为我在案例(1)中取得了成功(至少它有效)。现在,我不清楚案例(2)的正确程序。在本机DLL上,我有类似的东西:

void ReadAStruct(AStructNative &value)
{
    size_t length = GetArrayLength();
    BStructNative * bstructs = (BStructNative *)malloc(length * sizeof(BStructNative));
    /*fill bstructs*/
    value.length = length;
    value.bstructs = bstructs;
}

MarshalNativeToManaged的C#侧,我成功回读了数据,但我的问题是:

  1. 我应该在CleanUpNativeData(IntPtr pNativeData)做什么?对Marshal.FreeCoTaskMem(pNativeData)的调用给出了一个例外(说"这可能是由于堆的损坏......")
  2. 我想我必须在本机DLL上提供一个释放内存的方法。这里常见的是什么?考虑到DLL应该是可移植的并且可以从其他C ++应用程序中使用,标准是什么?我想我不应该有像FreeAStruct(AStructNative &value)这样的方法,否则这将产生结构的进一步编组,因此我应该做类似FreeAStruct()的事情并保持指向DLL中已分配内存的指针吗?

0 个答案:

没有答案