Szukaj…


Wprowadzenie do niebezpiecznego kodu

C # pozwala na używanie zmiennych wskaźnikowych w funkcji bloku kodu, gdy jest on oznaczony przez unsafe modyfikator. Niebezpieczny kod lub niezarządzany kod to blok kodu, który wykorzystuje zmienną wskaźnika.

Wskaźnik to zmienna, której wartością jest adres innej zmiennej, tj. Bezpośredni adres lokalizacji pamięci. podobnie jak w przypadku dowolnej zmiennej lub stałej, należy zadeklarować wskaźnik, zanim będzie można go użyć do przechowywania dowolnego adresu zmiennej.

Ogólna forma deklaracji wskaźnika to:

type *var-name;

Poniżej przedstawiono prawidłowe deklaracje wskaźnika:

int    *ip;    /* pointer to an integer */
double *dp;    /* pointer to a double */
float  *fp;    /* pointer to a float */
char   *ch     /* pointer to a character */

Poniższy przykład ilustruje użycie wskaźników w języku C # przy użyciu niebezpiecznego modyfikatora:

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();
      }
   }
}

Gdy powyższy kod został skompilowany i wykonany, daje następujący wynik:

Data is: 20
Address is: 99215364

Zamiast deklarować całą metodę jako niebezpieczną, możesz również zadeklarować część kodu jako niebezpieczną:

// safe code
unsafe
{
    // you can use pointers here
}
// safe code

Pobieranie wartości danych za pomocą wskaźnika

Możesz pobrać dane przechowywane w lokalizacji, do której odwołuje się zmienna wskaźnika, używając metody ToString (). Poniższy przykład pokazuje to:

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();
      }
   }
}

Kiedy powyższy kod został skompilowany i wykonany, daje następujący wynik:

Data is: 20
Data is: 20
Address is: 77128984

Przekazywanie wskaźników jako parametrów do metod

Możesz przekazać zmienną wskaźnikową do metody jako parametr. Poniższy przykład ilustruje to:

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();
      }
   }
}

Gdy powyższy kod zostanie skompilowany i wykonany, daje następujący wynik:

Before Swap: var1: 10, var2: 20
After Swap: var1: 20, var2: 10

Dostęp do elementów tablicy za pomocą wskaźnika

W języku C # nazwa tablicy i wskaźnik do typu danych takiego samego jak dane tablicy nie są tego samego typu zmiennej. Na przykład int *p i int[] p nie są tego samego typu. Możesz zwiększyć zmienną wskaźnika p ponieważ nie jest ona ustalona w pamięci, ale adres tablicy jest ustalony w pamięci i nie możesz tego zwiększyć.

Dlatego jeśli potrzebujesz uzyskać dostęp do danych tablicowych przy użyciu zmiennej wskaźnikowej, jak to zwykle robimy w C lub C ++, musisz naprawić wskaźnik za pomocą stałego słowa kluczowego.

Poniższy przykład pokazuje to:

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();
      }
   }
}

Kiedy powyższy kod został skompilowany i wykonany, daje następujący wynik:

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

Kompilowanie niebezpiecznego kodu

Aby skompilować niebezpieczny kod, musisz określić przełącznik wiersza polecenia /unsafe za pomocą kompilatora wiersza polecenia.

Na przykład, aby skompilować program o nazwie prog1.cs zawierający niebezpieczny kod, z wiersza poleceń, podaj polecenie:

csc /unsafe prog1.cs

Jeśli używasz programu Visual Studio IDE, musisz włączyć użycie niebezpiecznego kodu we właściwościach projektu.

wprowadź opis zdjęcia tutaj

Aby to zrobić:

  • Otwórz właściwości projektu, klikając dwukrotnie węzeł właściwości w Eksploratorze rozwiązań.
  • Kliknij kartę Kompilacja.
  • Wybierz opcję „Zezwalaj na niebezpieczny kod”


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow