C# Language
ポインタと安全でないコード
サーチ…
安全でないコードの紹介
C#では、 unsafe
修飾子でマークされているときにコードブロックの関数内でポインタ変数を使用できます。安全でないコードまたはアンマネージコードは、ポインタ変数を使用するコードブロックです。
ポインタは、値が別の変数のアドレス、つまりメモリ位置の直接アドレスである変数です。任意の変数または定数と同様に、変数アドレスを格納する前にポインタを宣言する必要があります。
ポインタ宣言の一般的な形式は次のとおりです。
type *var-name;
有効なポインタ宣言は次のとおりです。
int *ip; /* pointer to an integer */
double *dp; /* pointer to a double */
float *fp; /* pointer to a float */
char *ch /* pointer to a character */
次の例は、安全でない修飾子を使用してC#でポインタを使用する方法を示しています。
using System;
namespace UnsafeCodeApplication
{
class Program
{
static unsafe void Main(string[] args)
{
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} ", var);
Console.WriteLine("Address is: {0}", (int)p);
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
Data is: 20
Address is: 99215364
メソッド全体を安全でないと宣言する代わりに、コードの一部を安全でないものとして宣言することもできます。
// safe code
unsafe
{
// you can use pointers here
}
// safe code
ポインタを使用したデータ値の取得
ToString()メソッドを使用して、ポインタ変数が参照する場所に格納されているデータを取得できます。次の例はこれを示しています:
using System;
namespace UnsafeCodeApplication
{
class Program
{
public static void Main()
{
unsafe
{
int var = 20;
int* p = &var;
Console.WriteLine("Data is: {0} " , var);
Console.WriteLine("Data is: {0} " , p->ToString());
Console.WriteLine("Address is: {0} " , (int)p);
}
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
Data is: 20
Data is: 20
Address is: 77128984
メソッドへのパラメータとしてのポインタの受け渡し
ポインタ変数をメソッドにパラメータとして渡すことができます。次の例は、これを示しています。
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe void swap(int* p, int *q)
{
int temp = *p;
*p = *q;
*q = temp;
}
public unsafe static void Main()
{
TestPointer p = new TestPointer();
int var1 = 10;
int var2 = 20;
int* x = &var1;
int* y = &var2;
Console.WriteLine("Before Swap: var1:{0}, var2: {1}", var1, var2);
p.swap(x, y);
Console.WriteLine("After Swap: var1:{0}, var2: {1}", var1, var2);
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10
ポインタを使用した配列要素へのアクセス
C#では、配列名と、配列データと同じデータ型へのポインタは同じ変数型ではありません。たとえば、 int *p
とint[] p
は同じ型ではありません。ポインタ変数p
はメモリ内では固定されていませんが、配列アドレスはメモリ内で固定されているためインクリメントすることはできません。
したがって、以前はCやC ++で行っていたように、ポインタ変数を使用して配列データにアクセスする必要がある場合は、fixedキーワードを使用してポインタを修正する必要があります。
次の例はこれを示しています:
using System;
namespace UnsafeCodeApplication
{
class TestPointer
{
public unsafe static void Main()
{
int[] list = {10, 100, 200};
fixed(int *ptr = list)
/* let us have array address in pointer */
for ( int i = 0; i < 3; i++)
{
Console.WriteLine("Address of list[{0}]={1}",i,(int)(ptr + i));
Console.WriteLine("Value of list[{0}]={1}", i, *(ptr + i));
}
Console.ReadKey();
}
}
}
上記のコードをコンパイルして実行すると、次の結果が生成されます。
Address of list[0] = 31627168
Value of list[0] = 10
Address of list[1] = 31627172
Value of list[1] = 100
Address of list[2] = 31627176
Value of list[2] = 200
安全でないコードのコンパイル
安全でないコードをコンパイルするには、コマンドラインコンパイラで/unsafe
コマンドラインスイッチを指定する必要があります。
たとえば、安全でないコードを含むprog1.csという名前のプログラムをコマンドラインからコンパイルするには、次のコマンドを実行します。
csc /unsafe prog1.cs
Visual Studio IDEを使用している場合は、プロジェクトのプロパティで安全でないコードを使用できるようにする必要があります。
これをする:
- ソリューションエクスプローラでプロパティノードをダブルクリックしてプロジェクトプロパティを開きます。
- [ビルド]タブをクリックします。
- [安全でないコードを許可する]オプションを選択し、