6

ネイティブ関数がオブジェクトに対して何らかの処理を実行できるようにするために、.NET オブジェクト (オブジェクトを含む) の配列を固定したいと考えています。私が理解している限り、GCHandle.Alloc() ではこれを行うことができません。そのような配列には、blittable ではない参照 (およびオブジェクトにも参照が含まれる可能性がある) が含まれているためです。

これを達成するための他のオプションはありますか?非常にハック的な提案や、Mono を必要とする提案であれば問題ありません。

4

2 に答える 2

10

.NET の配列は、連続したメモリで表されます。つまり、メモリ内では、要素 0 の後、要素 1 が前の要素の直後、というように続きます。

で配列を固定すると、要素のリスト全体もメモリに固定され、アンマネージ コードで処理できることをGCHandle.Alloc意味します。

ただし、あなたが言及したように、型が blittable 型である場合にのみ意味があります (技術的には、これは真実ではありません。型がアンマネージ コードにマーシャリングできる場合ですが、blittable 間には多くの重複があります)。 P/Invoke/COM 相互運用層が自動的に処理する主要な型ともの)。

したがって、値型の配列がある場合は、呼び出すことができGCHandle.Alloc、配列が固定されます。ただし、P/Invoke レイヤーが既にこれを行っているので、気にする必要はありません。

配列が参照でいっぱいの場合、それを管理されていないコードにマーシャリングしても意味がありません。すべての参照を固定したとしても、型システムは参照がメモリ内で指している .NET 型をサポートしていないため、アンマネージ コードはメモリ内のその参照をどう処理するかわかりません。

.NET のクラスが本当にネイティブ構造のラッパー/.NET 表現である場合は、.NET でその構造の配列を作成し、すべてのデータをそこにコピーしてから、ネイティブ コードに送信することをお勧めします。 .

または、クラスを C++/cli で記述して、ネイティブ コードで .NET メンバーへのアクセスを容易にすることもできます。

于 2012-11-08T16:31:50.990 に答える
0

Marshal.AllocHGlobalとを見てみることができますMarshal.WriteIntPtr。これは、フレームワークがアンマネージメモリを操作するために提供する公式の方法です。しかし、それが役立つかどうかはわかりません。

編集

https://stackoverflow.com/a/878147/301525も参照してください

于 2012-11-08T16:37:26.087 に答える