1.4. fejezet, Unsafe kód, natív DLL kezelés

A managed kód kiváltja a memóriakezeléssel járó hibalehetőségeket. Akkor használjunk unsafe kódot, ha:

  • A lehető legjobb teljesítményt szeretnénk elérni egy rendkívül számításigényes feladathoz
  • .NET–en kívüli osztálykönyvtárakat akarunk használni

Unsafe kódrészben a memóriát pointer-eken keresztül érhetjük el közvetlenül. A programot parancssorból a /unsafe kapcsolóval fordítsuk le, Visual Studio-ban jobb klikk a projecten, Properties ablak, és a Build fülön jelöljük be az „Allow unsafe code” jelölőnégyzetet. Parancssorba így fordítható a program:

csc /unsafe main.cs

Példa az unsafe blokkra és publikus tulajdonságra:

namespace Homework4Unsafe
{
    class Test2Property
    {
        public unsafe int* x;
    }
 
    struct Test2Struct
    {
        public int x;
    }
 
    class Program
    {
        static void Main(string[] args)
        {
            unsafe
            {
                Test2Property t = new Test2Property();
                int y = 10;
                t.x = &y;
                Console.WriteLine(*t.x); // 10
 
                //Typed pointer
                int x = 20;
                int* p1 = &x;
                Console.WriteLine(*((int*)p1)); // 20
 
                byte z = 30;
                p1 = (int*)&z;
                //p1 = (byte*)&x; // build error
                Console.WriteLine(*((int*)p1)); // 30
 
                //void pointer
                void* p2 = &x;
                Console.WriteLine(*((int*)p2)); // 10
 
                Test2Struct t2 = new Test2Struct();
                t2.x = 100;
                Test2Struct* p3 = &t2;
                Console.WriteLine((*p3).x); // 100
                Console.WriteLine(p3->x); // 100
            }
            Console.ReadKey();
        }
    }
}

Fix objektumok

Referenciatípuson belül deklarált értéktípusok esetén (ilyenek a tömbelemek is) fixálni kell az objektum
helyzetét, hogy a GC ne mozdíthassa el.

  int[] array = new int[] { 1, 3, 5, 7, 11 };
  fixed (int* p = array)
  for (int i = 0; i < 5; ++i)
  {
    Console.WriteLine(*(p + i));
  }

Dynamic Link Library

File -> New Project -> Visual C# -> Class Library -> Name = Homework4Library

using System;
 
namespace Homework4Library
{
    public class TestClass
    {
        static public void PrintHelloWorld()
        {
            Console.Out.WriteLine("Hello world");
        }
    }
}

A Homework4Library projekt alkalmazása egyéb projektből

Solution Explorer -> [Project] -> Add reference... -> Browse... -> Homework4Library.dll

using System;
using Homework4Library;
 
namespace Homework4Native
{
    class Program
    {
        static void Main(string[] args)
        {
            TestClass.PrintHelloWorld();
        }
    }
}

Natív dll függvény hívások extern metódusokkal

using System;
using System.Runtime.InteropServices;
 
namespace Homework4Native
{
    class Program
    {
        public class API
        {
            [DllImport("user32.dll")]
            public static extern int MessageBox(int hWnd, string text, string caption, uint type);
        }
 
        static void Main(string[] args)
        {
            API.MessageBox(0, "Hello!", "Window title", 0);
        }
    }
}