C#
Özet - P/Invoke ve interop
DllImport, Marshal ve StructLayout'u birleştirerek bir yerel sarmalayıcı yazarsın.
Özet - P/Invoke ve interop
Bu grupta DllImport, Marshal, StructLayout, string marshalling ve delegate* konularını öğrendin. Bunlar C# ile yerel kodu (C kütüphaneleri, Win32 API) çağırmanın yollarıdır.
Doğru marshal türünü seçmek ve belleği elle yönetmek interop kodunun güvenliği için kritiktir. Şimdi küçük bir yerel sarmalayıcı yazalım.
Uygulama Point struct ve Marshal.SizeOf
[StructLayout(LayoutKind.Sequential)] struct Point { public int X; public int Y; } struct'ını ekle. Main'de Point p; p.X = 10; p.Y = 20; yaz, int size = Marshal.SizeOf<Point>(); ile boyut al, Console.WriteLine(size); yaz.
Örnek çözümü göster
[StructLayout(LayoutKind.Sequential)] struct Point { public int X; public int Y; } yaz. Main'de Point p; p.X = 10; p.Y = 20; int size = Marshal.SizeOf<Point>(); Console.WriteLine(size);
Örnek çözüm:
using System;
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
struct Point
{
public int X;
public int Y;
}
class Program
{
static void Main()
{
Point p;
p.X = 10;
p.Y = 20;
int size = Marshal.SizeOf<Point>();
Console.WriteLine(size);
}
}
Bellek ve yaşam döngüsü
Interop kodunda önemli olan: Marshal ile ayırdığın belleği mutlaka serbest bırak (FreeHGlobal). DllImport'ın otomatik marshal ettiği string'lerde buna gerek yoktur ama elle Marshal çağrılarında bellek sızıntısına dikkat et.
using deyimi veya try/finally ile serbest bırakmayı garantilemek en iyi yöntemdir. Bu, hata durumlarında bile kaynağın geri kazanılmasını sağlar.
Uygulama DllImport ile abs çağır
[DllImport("libc.so.6")] static extern int abs(int n); bildirimini ekle. Main'de int r = abs(-7); ile mutlak değer al, Console.WriteLine(r); ile yazdır.
Örnek çözümü göster
[DllImport("libc.so.6")] static extern int abs(int n); bildir. Main'de int r = abs(-7); Console.WriteLine(r);
Örnek çözüm:
using System;
using System.Runtime.InteropServices;
class Program
{
[DllImport("libc.so.6")]
static extern int abs(int n);
static void Main()
{
int r = abs(-7);
Console.WriteLine(r);
}
}
Kendini test et
-
Hangisi yönetilen string'i yerel belleğe kopyalar?
- Marshal.StringToHGlobalAnsi
- GC.Collect
- Thread.Sleep
- Console.WriteLine
Cevabı göster
Marshal.StringToHGlobalAnsi — Doğru. Marshal.StringToHGlobalAnsi string'i yerel belleğe koyar.
-
Kavramları eşleştir
- DllImport
- Yerel metot çağrısı
- Marshal
- Elle dönüşüm
- StructLayout
- Bellek düzeni
- delegate*
- Function pointer
Sıradaki ders: Thread sınıfı