我在C ++代码中有以下用于互操作的函数和结构:
extern "C" __declspec(dllexport) typedef struct
{
int num_vertices;
int *vertices;
} Vertex_List;
extern "C" __declspec(dllexport) typedef struct
{
int num_cycles;
Vertex_List *cycles;
} Cycle_List;
extern "C" __declspec(dllexport) typedef struct
{
int v1;
int v2;
} Edge;
extern "C" __declspec(dllexport) typedef struct
{
int num_edges;
Edge *edgeList;
} Edge_List;
extern "C" __declspec(dllexport) Cycle_List Traversal(Edge_List edgeList);
这是我对应的.Net结构代码:
[StructLayout(LayoutKind.Sequential)]
internal struct EdgeSpecial
{
public int v1;
public int v2;
}
[StructLayout(LayoutKind.Sequential)]
internal struct Edge_List
{
public int num_edges;
public IntPtr edgeList;
}
[StructLayout(LayoutKind.Sequential)]
internal struct Vertex_List
{
public int num_vertices;
public IntPtr vertices;
}
[StructLayout(LayoutKind.Sequential)]
internal struct Cycle_List
{
public int num_cycles;
public IntPtr cycles;
}
[DllImport("BoostAPI.dll")]
public static extern Cycle_List Traversal([In] Edge_List edgeList);
这就是我在.Net函数中调用的方式:
//converts from my edge structure to the interop structure
Edge_List edgeList = EdgeConvertor(edges);
//interop call
Cycle_List cycleInterop = GraphBoostInterop.Traversal(edgeList);
// converts from interop cycle structure to my .NET structure
var cycleList = CycleListConvertor(cycleInterop);
问题是,在cycleInterop
转换为我的数据结构cycleList
后,是否需要释放edgeList
和cycleInterop
?我应该在C ++中创建FreeCycle
或这样的代码,然后将结构传递给它以释放内存目的吗?如果是,怎么样?
编辑:这就是用C ++填充Cycle_List的方法;基本上我只是从类似的数据结构中复制信息(使用std::vector
)。
i=0;
Cycle_List cList;
cList.num_cycles=cycleList.CycleList.size();
cList.cycles=(Vertex_List*)malloc(cList.num_cycles*sizeof(Vertex_List));
for(std::vector<Cycle>::const_iterator it = cycleList.CycleList.begin(); it != cycleList.CycleList.end(); ++it)
{
Cycle cycle = *it;
Vertex_List vList;
vList.num_vertices = cycle.VertexList.size();
vList.vertices= (int*) malloc ( vList.num_vertices*sizeof(int));
j=0;
for(std::vector<int>::const_iterator intList=cycle.VertexList.begin(); intList!=cycle.VertexList.end(); ++intList)
{
vList.vertices[j++] = *intList;
}
cList.cycles[i++]=vList;
}
答案 0 :(得分:1)
释放的责任在于分配记忆的人。看起来很简单,这是黄金法则。
根据此规则,当非托管DLL返回指向非托管结构的指针时,表示它已分配内存。因此,释放内存需要调用非托管DLL以在完成后释放它 - 这似乎是在您完成将非托管指针转换为托管结构时。
我不熟悉您的非托管库,但我使用过OpenCV,它有cvRelease(**ptr)
释放内存并将指针重置为零。
答案 1 :(得分:1)
因为您在自己的C ++代码中填充Cycle_List
结构,所以应该编写第二个C ++函数来释放Cycle_List
结构。
由于您使用malloc
初始化Cycle_List::cycles
和Vertex_List::vertices
成员,因此您应该使用free
进行清理。
正如@Aliostad所说,“释放的责任在于分配记忆的人。”