2012-02-20 12 views
1

私はこのようなC#のからメソッドを呼び出すのです解放:はVC#にVC++からulong64配列を渡すとメモリ

[DllImport(@"C:\Hash.dll", 
    CallingConvention = CallingConvention.Cdecl)] 
    public static extern IntPtr ph_dct_videohash(
     string file, 
     ref int length); 


    static void Main(string[] args) 
    { 
      int length = 0; 
      ph_dct_videohash(@"C:\Users\shady\H.avi", ref length); 
      Console.Read(); 

    } 

をそしてここで私は、ライブラリから呼び出しています方法であるに

ulong64* ph_dct_videohash(const char *filename, int &Length){ 

CImgList<uint8_t> *keyframes = ph_getKeyFramesFromVideo(filename); 
if (keyframes == NULL) 
    return NULL; 

Length = keyframes->size(); 

ulong64 *hash = (ulong64*)malloc(sizeof(ulong64)*Length); 
//some code to fill the hash array 
return hash;} 

質問は、どのように私はC#で符号なし64ビットロング配列を取得し、それを使用した後にメモリを解放することです。それが私にとってガベージコレクタによって管理されるならば、それはさらに良いでしょう。

私はMarshal.copyを試しましたが、動作しませんでした。memリークが発生する恐れがあります(memが自動的に解放されるかどうかわかりません)。どんな助けもありがとう。ありがとう。

+2

を引数として渡してください。メモリの所有権の問題やコピーが不要です。 –

+0

引数を使って日付へのポインタを渡すと、C#で解放する必要がありますか?私はこの問題がどのように解決するのかよく分かりません。 – Tormentor308

+0

いいえ、管理対象メモリはガベージコレクタによって処理されます。 –

答えて

2

あなたが続くことができる2つの方法があります。

  1. あなたのライブラリへの「フリー」機能を追加し、ライブラリの側に割り当てられたリソースごとに明示的に呼び出します。これはライブラリ側のコード変更を最小限に抑える必要がありますが、IntPtrのためにラップパーをIDisposableのように自動的に作成しない限り、メモリを解放することを覚えておく必要があります。たとえば、次のクラスを使用できます。

  2. 内部でを割り当てる代わりに、バッファへのポインタを受け入れるようにパブリックライブラリの関数を変更します。これは、ライブラリ側で多くの変更を必要とする可能性がありますが、C#側でコードを簡素化します。

編集:ただ、それぞれのIntPtr結果のためにそれのインスタンスを作成

public class HashDllAutoPtr : IDisposable 
{ 
    [DllImport(@"C:\Hash.dll", CallingConvention = CallingConvention.Cdecl)] 
    public static extern void ph_dct_free(IntPtr ptr); 

    public HashDllAutoPtr(IntPtr ptr) 
    { 
     Ptr = ptr; 
    } 

    ~HashDllAutoPtr() 
    { 
     Dispose(); 
    } 

    public IntPtr Ptr 
    { 
     get; 
     private set; 
    } 

    #region IDisposable Members 

    public void Dispose() 
    { 
     if (Ptr != IntPtr.Zero) 
     { 
      ph_dct_free(Ptr); 
     } 
     Ptr = IntPtr.Zero; 
    } 

    #endregion 
} 

:最初の提案のためのsupplimentとして、あなたは以下のクラスを使用することができます。メモリを解放したいときに手動でDisposeに電話をかけることもできるし、ちょうどそれを止めておくこともでき、最終的にはGCによってピックアップされる(私は推奨しないが)。アンマネージデータの処理の詳細については、here

関連する問題