2010-12-06 11 views
2

私は相互運用のために設計されているC++コードに次の関数との構造を有する:呼び出し後にInterop構造メモリを解放する必要がありますか?

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); 

これは私がで私の呼び出しを行う方法です純関数:

//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に変換された後、I edgeListcycleInteropを解放する必要がありますよ?私はC++の内側FreeCycleまたはそのようなコードを作成し、メモリの目的を解放するためにそれに構造体を渡すべきか?はいの場合、どうですか?

編集:これはCycle_ListはC++に移入された方法です。基本的には、同様のデータ構造(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

[QuickGraph(http://quickgraph.codeplex.com/)C#で書かれた優れたグラフライブラリです。そのAPIはBoostによく一致するように設計されています。 –

+0

@Tim、そのままでは、アルゴリズムの中にはQuickGraphでは利用できないものもあります。 – Graviton

+0

十分です。あなたの質問に答えて: 'Cycle_List'は' IntPtr'を含んでいますので、あなたは何かを解放する必要があります。しかし、適切な機能はBoostのどこかにあります。 Boostのドキュメントを読むべきです。 –

答えて

1

リリースの責任は、誰でもメモリを割り当てたことによるものです。見た目は単純ですが、これはゴールデンルールです。

このルールによれば、アンマネージDLLが管理されていない構造体へのポインタを返した場合、がメモリを割り当てていることを意味します。あなたが管理構造体への管理対象外のポインタを変換終える時にあると思われる - だから、メモリを解放する作業が完了したときにそれを解放するために、非管理DLLを呼び出す必要であろう。

私はあなたのアンマネージドライブラリに慣れていませんが、OpenCVを使用していて、メモリを解放してポインタをゼロにリセットするcvRelease(**ptr)があります。

1

Cycle_List構造体を独自のC++コードの中に埋め込むので、Cycle_List構造体を解放する2番目のC++関数を記述する必要があります。

あなたはCycle_List::cyclesVertex_List::verticesメンバーを初期化するためにmallocを使用しているので、あなたはそれらをクリーンアップするfreeを使用する必要があります。 @Aliostadとして

は「リリースの責任は、メモリ割り当てた誰である」、と言います。

関連する問題