IntPtr.Add, IntPtr.Subtract

いつの間にこんなメソッドが!

.NET Framework 2.0ばかり使っていたので、長いこと気づきませんでした。みんなのつよーい味方、IntPtr構造体に、AddメソッドとSubtractメソッドができていました(どちらもstatic)。また、同じ機能で+と-の演算子としても定義されています。

これで、ポインタの加算・減算ができます。あくまでずらし幅はバイト単位なので、C/C++でポインタに対し++や--で書いていたところは、たいていは += sizeof(int); などと書く必要があります。

使用例

かなりまどろっこしく、double配列の要素にポインタでアクセスします。

double[] array = new double[] { 1.1, 2.2, 3.3, 4.4 };

GCHandle handle = GCHandle.Alloc(array, GCHandleType.Pinned);
{
    IntPtr ptr = handle.AddrOfPinnedObject();
    for (int i = 0; i < array.Length; i++)
    {
        long longValue = Marshal.ReadInt64(ptr);
        double doubleValue = BitConverter.Int64BitsToDouble(longValue);
        Console.WriteLine(doubleValue);

        ptr += sizeof(double);
    }
}
handle.Free();


以前は、ポインタをずらすところは以下のように書く必要がありました。楽になりますね、かすかに。

ptr = new IntPtr(ptr.ToInt64() + sizeof(double));

unsafeによる例

しかし以下のほうが断然楽です。やはりunsafe、イケてます。IntPtrが影も形も無いですが。

unsafe
{
    double[] array = new double[] { 1.1, 2.2, 3.3, 4.4 };

    fixed(double *pArray = array) 
    {
        double* ptr = pArray;
        for (int i = 0; i < array.Length; i++)
        {                    
            Console.WriteLine(*ptr);
            ptr++;
        }
    }
}