调用后是否应释放互操作结构内存?

时间:2010-12-06 13:16:59

标签: .net c++ interop

我在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后,是否需要释放edgeListcycleInterop?我应该在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;



  }

2 个答案:

答案 0 :(得分:1)

释放的责任在于分配记忆的人。看起来很简单,这是黄金法则。

根据此规则,当非托管DLL返回指向非托管结构的指针时,表示已分配内存。因此,释放内存需要调用非托管DLL以在完成后释放它 - 这似乎是在您完成将非托管指针转换为托管结构时。

我不熟悉您的非托管库,但我使用过OpenCV,它有cvRelease(**ptr)释放内存并将指针重置为零。

答案 1 :(得分:1)

因为您在自己的C ++代码中填充Cycle_List结构,所以应该编写第二个C ++函数来释放Cycle_List结构。

由于您使用malloc初始化Cycle_List::cyclesVertex_List::vertices成员,因此您应该使用free进行清理。

正如@Aliostad所说,“释放的责任在于分配记忆的人。”