0

まず、環境に関する基本情報: Win7-x64 で 32 ビットをターゲットとする c# .net 4.0 を使用しています。

事前に割り当てられた大規模な配列があります。関数では、この配列内の任意のポイントへのポインターを返したいので、呼び出し元の関数はどこに書き込むかを知ることができます。元:

class SomeClass {
    void function_that_uses_the_array() {
       Byte [] whereToWrite = getEmptyPtrLocation(1200);
       Array.Copy(sourceArray, whereToWrite, ...);
    }
}

class DataProvider {
    int MAX_SIZE = 1024*1024*64;
    Byte [] dataArray = new Byte[MAX_SIZE];
    int emptyPtr=0;
    Byte[] getEmptyPtrLocation(int requestedBytes) {
       int ref = emptyPtr;
       emptyPtr += requestedBytes;
       return dataArray[ref];
    }
}

基本的に、メモリの大きなチャンクを事前に割り当て、このメモリ ブロックの任意の長さの部分を予約し、他のクラス/関数がメモリのその部分を使用できるようにします。

上記の例では、getEmptyPtrLocation 関数が正しくありません。Byte[] を返すと宣言されていますが、1 バイト値を返そうとしています。

ありがとう

4

5 に答える 5

4

他の人が言ったように、C# ではこれを行うことはできません。一般的には、そのようなことはすべきではありません。システムを操作する - ガベージ コレクターなどを活用します。

そうは言っても、同様のことをしたい場合で、クライアントが割り当てられたスロットをオーバーランしないことを信頼できる場合は、メソッドArraySegment<byte>を の代わりに返すことができますbyte[]。それは「配列の一部」を表します。明らかに、.NET のほとんどのメソッドは使用しませんが、使用したいいくつかのより一般的な操作のターゲットとして、.NET を使用して拡張メソッドを作成できる可能性ArraySegment<T>あります。

于 2011-02-02T15:22:06.023 に答える
3

これはかなり古い投稿ですが、私には簡単な解決策があります。この質問には「すべきではない」などの答えがたくさんあるようです。何かをする方法があれば、それを使ってみませんか?

しかしそれはさておき、あなたは以下を使うことができます

int[] array = new int[1337];
position = 69;
void* pointer = (void*)Marshal.UnsafeAddrOfPinnedArrayElement(array, position);
于 2013-03-08T16:04:16.457 に答える
3

これは C++ ではなく C# です。ここではガベージ コレクターに対して真に取り組んでいます。一般に、C# ではメモリ割り当てが非常に高速です。また、C++ で事前割り当てを行う主な理由の 1 つであるメモリの断片化もありません。

そうは言っても、あなたはまだそれをやりたいと思っています。配列のインデックスと長さを使用するだけなのでArray.Copy、その位置に書き込むことができます。

編集:

ArraySegment<T>他の人があなたのニーズにより適していると指摘しているように、消費者を配列のスライスだけに制限し、元の配列のコンテンツを更新する前に別の配列を割り当てる必要はありません (ArraySegment で表されます)。

于 2011-02-02T15:13:49.580 に答える
2

アンマネージ コードを使用せずに、C# の配列の中央へのポインターを返すことはできません。できることは、データを入力する場所の配列インデックスを返すことだけです。

于 2011-02-02T15:10:31.743 に答える
1

これを行う必要がある場合、オプションには、(Jon Skeet が指摘したように) ArraySegment を返すか、Streams を使用することが含まれます。このコンストラクターを使用して、配列のサブセットである MemoryStream を返すことができます。ただし、オフセット操作としてではなく、ストリーム操作としてすべてのメモリの読み取りと書き込みを処理する必要があります。

于 2011-02-02T15:27:08.130 に答える