2012-01-26 26 views
7

Cで使用するいくつかの関数をエクスポートするモジュールをC#で作成します。 C < - > C#の間で渡される構造体のために、いくつかのメモリを割り当てる必要があります。mallocとMarshal.AllocHGlobalとの間に違いがありますか?

私はmallocで行い、C#ではMarshal.AllocHGlobal()(Cに渡す管理されていないメモリを割り当てる)で行います。

Marshal.AllocHGlobalで割り当てられたメモリをfree()し、mallocで割り当てられたMarshal.FreeHGlobal()でメモリを解放すると問題はありますか?

おかげ

+0

すべてのお返事ありがとう – bzamfir

+0

ありがとう。実際に私がしたのは、libに渡された構造体を作成するときに、呼び出されたプログラムで使用することをお勧めしている、libのエクスポートされた関数AllocateMemとFreeMemを作成することでした。しかし、私はこのルールを遵守しておらず、malloc(または何か他のもの)で割り当てられたいくつかの構造体を自分のlibに渡すことに疑問を抱いていました。 – bzamfir

+0

問題は、構造体には、私は割り当てる必要があり、呼び出しコードに渡す必要があります(文字列)の文字へのいくつかのポインタがあります。呼び出し元のコードがfree()でメモリを解放しようとするとどうなりますか?だからこそ私はFreeHGlobalで実装したFreeMemを作成し、progを呼び出す際にメモリを解放するために使用しています。それ以外の場合は、コードを呼び出すプログラマの責任です。 – bzamfir

答えて

15

黄金のルールは、あなたがメモリを割り当てるために使用したのと同じヒープから割り当てを解除しなければならないということです。

malloc()で割り当てる場合は、同じC RTLからfree()で割り当てを解除する必要があります。同様に、管理サイドの場合、AllocHGlobal()FreeHGlobal()と均衡する必要があります。

ここで、は、Win32関数LocalAllocを呼び出して実装されています。したがって、ネイティブ側のLocalFreeへの呼び出しでそのようなメモリを解放することができます。およびその逆。

ネイティブと管理対象の間で共有されるヒープを使用する場合は、COMヒープを使用する方が一般的です。ネイティブ側ではCoTaskMemAlloc()CoTaskMemFree()を使用してください。管理サイドでは、Marshal.AllocCoTaskMem()Marshal.FreeCoTaskMem()を使用します。

ただし、このようなシステムの設計は避けてください。管理された側に割り当てられたすべてのメモリがそこで割り当てが解除され、ネイティブ側にも同様にルールが適用されるのはずっと簡単です。そのルールに従わなければ、誰が何を担当しているかをすぐに見失う可能性が高くなります。

4

問題が発生する場合もありません。これは完全に実装に依存します。アプリの機能の実装の詳細を決して頼りにしないでください!

だから私はMarshal.AllocHGlobal()malloc()Marshal.FreeHGlobal()free()横を使用するないをお勧めします。

ライブラリを使用すると厄介な問題に遭遇する例があります。それは魔法のようなものです。それはわからないかもしれません。

+1

いいえ、それは全く機能しません!可能性はありますか? –

+0

@DavidHeffernan興味深い!私たちはアプリでこれを持っていましたし、通常Monoでうまくいきました。すばらしいライブラリで壊れ始めたので、調査しました。 –

+1

実際にはうまくいかなかったようです。しかしモノは違うかもしれません。私はMSを想定しています。私のコメントの最終的なものです。 –

関連する問題