Поиск…


Введение в небезопасный код

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, вам необходимо включить использование небезопасного кода в свойствах проекта.

введите описание изображения здесь

Сделать это:

  • Откройте свойства проекта, дважды щелкнув узел свойств в обозревателе решений.
  • Перейдите на вкладку «Сборка».
  • Выберите параметр «Разрешить небезопасный код»


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow