匣の向こう側 - あまりに.NETな
C#を始めて、まず迷ったのが、メモリの使い方。
今までは、BYTEアレイのポインタを扱っていたのですが、C#ではどうすればよいか、、、
割り当てについては、何のことはない、C/C++と同じように、
Byte data = new Byte[nSize];
というふうに、割り当てれば良かっただけのことですが、C#ではメモリのアドレスを扱うのではなく、すべてがオブジェクトとして扱われます。
すべてのオブジェクトは、参照カウンタ付きで、直接操作するのは、有無を言わさず参照を扱うことになります。
言うなれば、ポインタがまるっきり隠され、ポインタをラップしたオブジェクトの参照を扱うような感じだと思います。
で、また困りました。
メモリをコピーする方法が見つかりません。
たいていは、配列のラッパクラス(Array)に組み込まれているのかと思い、メンバを調べると、CopyTo() というそれっぽい関数が見つかったのですが、引数が少なすぎて、必要な条件を入れられないし、何とも不思議な動作をするので、当惑してしまいました。
困り果てて、ネットで検索すると(と言うか、その前に参考書なりMSDNなりを読め!!と言われそうですが、、、 ^^;)、ありました、memcpy()のC#版。
Buffer.BlockCopy(src, srcOffset, dst, dstOffset, count);
これこそ、まさに必要としていた関数だ!
(2012/11/19 追記)
このメソッドは、count には、バイト数で指定するんですね。
で、配列の次元が異なっていても、コピーできるようです。
たとえば、次の様な配列のコピーも出来ました。
double[,] src = new double[4, 4] {
{ 1, 2, 3, 4 }, { 5, 6, 7, 8 },
{ 9, 10, 11, 12 }, { 13, 14, 15, 16 } };
double[] dst = new double[16];
Buffer.BlockCopy(src, 0, dst, 0, 16 * sizeof(double));
注意点としては、src と dst の順番が memcpy と逆という事か。。。