Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Yönetilmeyen birçok işlev, işleve parametre olarak yapıların üyelerini (Visual Basic'te kullanıcı tanımlı türler) veya yönetilen kodda tanımlanan sınıfların üyelerini geçirmenizi bekler. Platform çağrısı kullanarak yapıları veya sınıfları yönetilmeyen koda geçirirken, özgün düzeni ve hizalamayı korumak için ek bilgiler sağlamanız gerekir. Bu konu, biçimlendirilmiş türleri tanımlamak için kullandığınız özniteliğini tanıtır StructLayoutAttribute . Yönetilen yapılar ve sınıflar için, numaralandırma tarafından sağlanan birkaç öngörülebilir düzen davranışı arasından seçim yapabilirsiniz.
Bu konuda sunulan kavramların merkezi, yapı ve sınıf türleri arasındaki önemli bir farktır. Yapılar değer türleridir ve sınıflar başvuru türleridir; sınıflar her zaman en az bir bellek dolaylı düzeyi (değer işaretçisi) sağlar. Yönetilmeyen işlevler genellikle aşağıdaki tablonun ilk sütunundaki imzalar tarafından gösterildiği gibi dolaylı işlem gerektirdiğinden bu fark önemlidir. Kalan sütunlardaki yönetilen yapı ve sınıf bildirimleri, bildiriminizdeki dolaylılık düzeyini ne derece ayarlayabileceğinizi gösterir. Hem Visual Basic hem de Visual C# için bildirimler sağlanır.
| Yönetilmeyen imza | Yönetilen bildirim: dolaylı yok Structure MyTypestruct MyType; |
Yönetilen bildirim: bir dolaylılık düzeyi Class MyTypeclass MyType; |
|---|---|---|
DoWork(MyType x);Sıfır dolaylılık düzeyi talep ediyor. |
DoWork(ByVal x As MyType) DoWork(MyType x)Dolaylılık seviyesini sıfıra indirir. |
Zaten bir dolaylılık düzeyi olduğundan mümkün değildir. |
DoWork(MyType* x);Bir düzeyde dolaylılık talep eder. |
DoWork(ByRef x As MyType) DoWork(ref MyType x)Bir düzey dolaylılık ekler. |
DoWork(ByVal x As MyType) DoWork(MyType x)Dolaylılık seviyesini sıfıra indirir. |
DoWork(MyType** x);İki düzeyde dolaylılık talep ediyor. |
ByRef ByRef veya ref ref kullanılamadığı için mümkün değildir. |
DoWork(ByRef x As MyType) DoWork(ref MyType x)Bir düzey dolaylılık ekler. |
Tabloda platform çağırma bildirimleri için aşağıdaki yönergeler açıklanmaktadır:
Yönetilmeyen işlev dolaylılık gerektirmediğinde, değer olarak geçirilen bir yapı kullanın.
Yönetilmeyen bir işlev bir dolaylılık düzeyi gerektirdiğinde, başvuru ile aktarılan yapıyı veya değer ile aktarılan bir sınıfı kullanın.
Yönetilmeyen işlev iki düzeyde dolaylılık gerektirdiğinde referans ile geçirilen bir sınıf kullanın.
Yapıları Tanımlama ve Geçirme
Aşağıdaki örnek, yönetilen kodda Point ve Rect yapılarını nasıl tanımlayacağınızı ve türleri User32.dll dosyasındaki PtInRect fonksiyonuna parametre olarak nasıl geçireceğinizi göstermektedir.
PtInRect aşağıdaki yönetilmeyen imzaya sahiptir:
BOOL PtInRect(const RECT *lprc, POINT pt);
İşlev bir RECT türüne işaretçi beklediğinden, Rect yapısını referans olarak geçirmeniz gerektiğine dikkat edin.
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential)> Public Structure Point
Public x As Integer
Public y As Integer
End Structure
Public Structure <StructLayout(LayoutKind.Explicit)> Rect
<FieldOffset(0)> Public left As Integer
<FieldOffset(4)> Public top As Integer
<FieldOffset(8)> Public right As Integer
<FieldOffset(12)> Public bottom As Integer
End Structure
Friend Class NativeMethods
Friend Declare Auto Function PtInRect Lib "user32.dll" (
ByRef r As Rect, p As Point) As Boolean
End Class
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public struct Point {
public int x;
public int y;
}
[StructLayout(LayoutKind.Explicit)]
public struct Rect {
[FieldOffset(0)] public int left;
[FieldOffset(4)] public int top;
[FieldOffset(8)] public int right;
[FieldOffset(12)] public int bottom;
}
internal static class NativeMethods
{
[DllImport("User32.dll")]
internal static extern bool PtInRect(ref Rect r, Point p);
}
Sınıfları Bildirme ve Geçirme
Sınıfın üyelerini, sınıfın sabit bir üye düzenine sahip olduğu sürece yönetilmeyen DLL işlevine geçirebilirsiniz. Aşağıdaki örnek, sıralı sırada tanımlanan sınıfın MySystemTime üyelerini User32.dll dosyasındaki öğesine GetSystemTime nasıl geçirebileceğinizi gösterir.
GetSystemTime aşağıdaki yönetilmeyen imzaya sahiptir:
void GetSystemTime(SYSTEMTIME* SystemTime);
Değer türlerinden farklı olarak, sınıfların her zaman en az bir dolaylı düzeyi vardır.
Imports System.Runtime.InteropServices
<StructLayout(LayoutKind.Sequential)> Public Class MySystemTime
Public wYear As Short
Public wMonth As Short
Public wDayOfWeek As Short
Public wDay As Short
Public wHour As Short
Public wMinute As Short
Public wSecond As Short
Public wMiliseconds As Short
End Class
Friend Class NativeMethods
Friend Declare Auto Sub GetSystemTime Lib "Kernel32.dll" (
sysTime As MySystemTime)
Friend Declare Auto Function MessageBox Lib "User32.dll" (
hWnd As IntPtr, lpText As String, lpCaption As String, uType As UInteger) As Integer
End Class
Public Class TestPlatformInvoke
Public Shared Sub Main()
Dim sysTime As New MySystemTime()
NativeMethods.GetSystemTime(sysTime)
Dim dt As String
dt = "System time is:" & ControlChars.CrLf & _
"Year: " & sysTime.wYear & _
ControlChars.CrLf & "Month: " & sysTime.wMonth & _
ControlChars.CrLf & "DayOfWeek: " & sysTime.wDayOfWeek & _
ControlChars.CrLf & "Day: " & sysTime.wDay
NativeMethods.MessageBox(IntPtr.Zero, dt, "Platform Invoke Sample", 0)
End Sub
End Class
[StructLayout(LayoutKind.Sequential)]
public class MySystemTime {
public ushort wYear;
public ushort wMonth;
public ushort wDayOfWeek;
public ushort wDay;
public ushort wHour;
public ushort wMinute;
public ushort wSecond;
public ushort wMilliseconds;
}
internal static class NativeMethods
{
[DllImport("Kernel32.dll")]
internal static extern void GetSystemTime(MySystemTime st);
[DllImport("user32.dll", CharSet = CharSet.Auto)]
internal static extern int MessageBox(
IntPtr hWnd, string lpText, string lpCaption, uint uType);
}
public class TestPlatformInvoke
{
public static void Main()
{
MySystemTime sysTime = new MySystemTime();
NativeMethods.GetSystemTime(sysTime);
string dt;
dt = "System time is: \n" +
"Year: " + sysTime.wYear + "\n" +
"Month: " + sysTime.wMonth + "\n" +
"DayOfWeek: " + sysTime.wDayOfWeek + "\n" +
"Day: " + sysTime.wDay;
NativeMethods.MessageBox(IntPtr.Zero, dt, "Platform Invoke Sample", 0);
}
}