我的主要应用程序是在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#侧,我成功回读了数据,但我的问题是:
CleanUpNativeData(IntPtr pNativeData)
做什么?对Marshal.FreeCoTaskMem(pNativeData)
的调用给出了一个例外(说"这可能是由于堆的损坏......")FreeAStruct(AStructNative &value)
这样的方法,否则这将产生结构的进一步编组,因此我应该做类似FreeAStruct()
的事情并保持指向DLL中已分配内存的指针吗?