我在 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
和循环互操作
?我应该在 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;
}
最佳答案
释放的责任由分配内存的人负责。看起来很简单,但这是黄金法则。
根据这条规则,当一个非托管 DLL 向我返回一个指向非托管结构的指针时,这意味着它 已经分配了内存。因此释放内存需要在完成后调用非托管 DLL 来释放它——这似乎是在您完成将非托管指针转换为托管结构时。
我不熟悉你的非托管库,但我使用过 OpenCV,它有 cvRelease(**ptr)
释放内存并将指针重置为零。
关于.net - 互操作结构内存应该在调用后释放吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4366756/