6

.netオブジェクトのアドレスを取得することができました

GCHandle objHandle = GCHandle.Alloc(obj,GCHandleType.WeakTrackResurrection);
int address = GCHandle.ToIntPtr(objHandle).ToInt32();  

そして私はオブジェクトを思い出すことができます

Object obj = GCHandle.FromIntPtr(IntPtr(address)).Target;

目的は、アドレスをネイティブクラスに格納し、どのネイティブオブジェクトがどの.netオブジェクトに関連付けられているかに関する情報を取得することです。
割り当てのためにアドレスが変更されないことを確認してください、それは本当ですか、それとも誰かが私の目的を果たすためのより良いアイデアを持っていますか?

ありがとう

4

4 に答える 4

7

GCがオブジェクトを移動するときに、GCHandleを固定してオブジェクトの移動を停止すると、固定されていないポインタが無効になる可能性があります。オブジェクトを固定すると、オブジェクトの移動が停止します。

GCHandle handle = GCHandle.Alloc(obj, GCHandleType.Pinned);
IntPtr ptr = handle.AddrOfPinnedObject();

完了したら、ハンドルを解放する必要もあります。

handle.Free();
于 2010-11-04T13:20:20.053 に答える
6

Timとthecoopが指摘しているように、GCHandle.Allocはガベージコレクションを防ぐことができますが、オブジェクトを固定しない限り、GCがオブジェクトを移動する可能性があるため、実際のオブジェクトアドレスは変更される可能性があります。さらに、あなたのコードは使用してGCHandleType.WeakTrackResurrectionおり、それはガベージコレクションを妨げることはありません。GCHandle.ToIntPtrアンマネージドコールでラウンドトリップできるハンドルのアドレスを提供します。実際のオブジェクトアドレスはAddrOfPinnedObjectメソッドによって指定されます。

とはいえ、IMOの場合、コードは.NETオブジェクトをアンマネージオブジェクトに関連付ける目的に役立つ可能性があります。これは、GCHandle.To / FromIntPtrが正しいGCHandleを返し、それを介して.NETオブジェクトに到達できるためです(ガベージコレクションされていない場合)。IMO、実際のオブジェクトアドレスが変更されたかどうかは重要ではありません。

于 2010-11-04T13:31:03.997 に答える
2

あなたが得ているのは実際には住所ではありません。

お気づきのように、ほとんどの場合、アドレスのように機能し、GCHandle.FromIntPtrを使用してオブジェクトを呼び出すことができます。ただし、興味深い問題は、GCHandleType.WeakTrackResurrectionを使用していることです。

弱く参照されているオブジェクトが収集された場合(GCHandleによって弱く参照されているだけなので、おそらく収集できます)、IntPtrが残っており、GCHandle.FromIntPtr()に渡すことができます。そうすると、IntPtrがリサイクルされていないと仮定して、nullに戻ります。

(IntPtrが何らかの理由でCLRによってリサイクルされた場合は、問題が発生しています。これが発生するかどうかはわかりません。)

オブジェクトへの強力な参照が必要な場合は、 GCHandleType.NormalまたはGCHandleType.Pinned(アンマネージコードでオブジェクトのアドレスを取得する必要がある場合)のいずれかを使用することをお勧めします。

(GCHandleType.Pinnedを使用するには、オブジェクトがプリミティブであるか、[StructLayout]属性を持っているか、そのようなオブジェクトの配列である必要があります。)

于 2011-01-19T00:26:56.873 に答える
1

割り当てのためにアドレスが変更されないことを確認してください、それは本当ですか

管理対象オブジェクトのアドレス変更されます。ガベージコレクタは、メモリ内のオブジェクトを自由に移動できます。ガベージコレクターが実行されると、未使用のオブジェクトが収集され、残りのオブジェクトが再配置されて、管理対象ヒープの全体的なサイズが最小化されます。

誰かが私の目的を果たすためのより良いアイデアを持っていますか?

管理対象オブジェクトへのポインタを長期間保持するための良い方法が見つかるかどうかはわかりません。オブジェクトをメモリに固定し、その方法でアドレスを取得することは可能ですが、C#では、単一のメソッド内でのみオブジェクトを固定することができます。

ポインタを取得したら、ポインタをどのように処理するかをより詳細に説明すると役立ちます。

于 2010-11-04T13:20:12.470 に答える