2011-07-16 34 views
9

私はデータを取得するC++関数を持っていて、C#から呼び出しました。この関数はSAFEARRAYへのポインタを取得し、文字列でポップします(SysAllocStringを使用)。C++ DLLからSAFEARRAYを解放し、C#

すべては問題ありませんが、プログラムはメモリをリークしています。

私は少し検索を行なったし、私はメソッドのシグネチャにこの属性を追加するとことがわかった:

[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] 
out string[] strServerList 

私は(それが割り当てられた)は、C++のコードでそれを解放する必要があるので、私はこの機能

を作成
[DllImport("Native.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "DeallocateExternal")] 
internal static extern void DeallocateExternal(
[MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)] 
out string[] strServerList); 

そして、私のdllに私はこのコード

void DeallocateExternal(SAFEARRAY** psa) 
{ 
    LONG cDims = SafeArrayGetDim(*psa); 
    BSTR* pvData = (BSTR*)((*psa)->pvData); 
    for (LONG x = 0; x < cDims; x++) 
    { 
     SysFreeString(pvData[x]); 
    } 
    SafeArrayDestroy(*psa); 
} 

を書いたが、私は例外が発生しました:

型「System.AccessViolationException」の未処理の例外はTester.exe

で発生しました追加情報:読み取りまたは書き込み保護されているメモリをしようとしました。これはしばしば、他のメモリが壊れていることを示します。

どうしたのですか?

+1

SafeArrayGetDimではなくSafeArrayGetUBoundを使用する必要があります。http://msdn.microsoft.com/en-us/library/aed339d5-d962-4adc-ac01-6c15a54c51ca%28VS.85%29 – Yahia

答えて

5

は、私はあなたが試してみてくださいと思う:

... 
SafeArrayDestroy(*psa); 
*psa = NULL 
... 

この理由は、.NETマーシャラーはに無効(解放された)メモリへのポインタを変換しようとしますので、あなたは、outとしてstrServerListを宣言しているということです文字列の配列。例外が発生する可能性があります。

関連する問題