Farklı Dizi Türlerini Sıralama
Dizi, yönetilen kodda aynı türde bir veya daha fazla öğe içeren bir başvuru türüdür. Diziler başvuru türleri olsa da, yönetilmeyen işlevlere In parametreleri olarak geçirilir. Bu davranış, yönetilen dizilerin yönetilen nesnelere geçirilme biçimiyle tutarsızdır ve bu da In/Out parametreleridir. Ek ayrıntılar için bkz . Kopyalama ve Sabitleme.
Aşağıdaki tabloda diziler için sıralama seçenekleri listelenmiştir ve bunların kullanımı açıklanmaktadır.
Dizi | Açıklama |
---|---|
Değere göre tamsayılar. | Bir tamsayı dizisini In parametresi olarak geçirir. |
Başvuruya göre tamsayılar. | Bir tamsayı dizisini In/Out parametresi olarak geçirir. |
Değere göre tamsayılar (iki boyutlu). | Bir tamsayı matrisini In parametresi olarak geçirir. |
Değere göre dizeler. | Dize dizisini In parametresi olarak geçirir. |
Tamsayılar içeren yapıların. | Tamsayılar içeren bir yapı dizisini In parametresi olarak geçirir. |
Dizeleri olan yapıların. | Yalnızca dizeleri içeren bir yapı dizisini In/Out parametresi olarak geçirir. Dizinin üyeleri değiştirilebilir. |
Örnek
Bu örnek, aşağıdaki dizi türlerinin nasıl geçir yapılacağını gösterir:
Değere göre tamsayı dizisi.
Başvuruya göre yeniden boyutlandırılabilir tamsayı dizisi.
Değere göre tamsayıların çok boyutlu dizisi (matris).
Değere göre dize dizisi.
Tamsayılar içeren yapı dizisi.
Dizeleri olan yapı dizisi.
Bir dizi başvuruya göre açıkça sıralanmadığı sürece, varsayılan davranış diziyi In parametresi olarak sıralar. ve OutAttribute özniteliklerini açıkça uygulayarak InAttribute bu davranışı değiştirebilirsiniz.
Diziler örneği, özgün işlev bildirimiyle gösterilen aşağıdaki yönetilmeyen işlevleri kullanır:
testArrayOfInts PinvokeLib.dll dışarı aktarıldı.
int TestArrayOfInts(int* pArray, int pSize);
TestRefArrayOfInts PinvokeLib.dll dışarı aktarıldı.
int TestRefArrayOfInts(int** ppArray, int* pSize);
TestMatrixOfInts PinvokeLib.dll dışarı aktarıldı.
int TestMatrixOfInts(int pMatrix[][COL_DIM], int row);
testArrayOfStrings PinvokeLib.dll dışarı aktarıldı.
int TestArrayOfStrings(char** ppStrArray, int size);
PinvokeLib.dll dışarı aktarılan TestArrayOfStructs .
int TestArrayOfStructs(MYPOINT* pPointArray, int size);
TestArrayOfStructs2 , PinvokeLib.dll dışarı aktarıldı.
int TestArrayOfStructs2 (MYPERSON* pPersonArray, int size);
PinvokeLib.dll, daha önce listelenen işlevlerin ve MYPOINT ve MYPERSON adlı iki yapı değişkeninin uygulamalarını içeren özel bir yönetilmeyen kitaplıktır. Yapılar aşağıdaki öğeleri içerir:
typedef struct _MYPOINT
{
int x;
int y;
} MYPOINT;
typedef struct _MYPERSON
{
char* first;
char* last;
} MYPERSON;
Bu örnekte ve MyPoint
MyPerson
yapıları katıştırılmış türler içerir. StructLayoutAttribute özniteliği, üyelerin bellekte sırayla, göründükleri sırayla düzenlendiklerinden emin olmak için ayarlanır.
sınıfı, NativeMethods
sınıfı tarafından App
çağrılan bir yöntem kümesi içerir. Dizileri geçirme hakkında belirli ayrıntılar için aşağıdaki örnekteki açıklamalara bakın. Başvuru türü olan bir dizi, varsayılan olarak In parametresi olarak geçirilir. Çağıranın sonuçları alması için InAttribute ve OutAttribute, diziyi içeren bağımsız değişkene açıkça uygulanmalıdır.
Prototipleri Bildirme
// Declares a managed structure for each unmanaged structure.
[StructLayout(LayoutKind.Sequential)]
public struct MyPoint
{
public int X;
public int Y;
public MyPoint(int x, int y)
{
this.X = x;
this.Y = y;
}
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]
public struct MyPerson
{
public string First;
public string Last;
public MyPerson(string first, string last)
{
this.First = first;
this.Last = last;
}
}
internal static class NativeMethods
{
// Declares a managed prototype for an array of integers by value.
// The array size cannot be changed, but the array is copied back.
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int TestArrayOfInts(
[In, Out] int[] array, int size);
// Declares a managed prototype for an array of integers by reference.
// The array size can change, but the array is not copied back
// automatically because the marshaler does not know the resulting size.
// The copy must be performed manually.
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int TestRefArrayOfInts(
ref IntPtr array, ref int size);
// Declares a managed prototype for a matrix of integers by value.
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int TestMatrixOfInts(
[In, Out] int[,] pMatrix, int row);
// Declares a managed prototype for an array of strings by value.
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int TestArrayOfstrings(
[In, Out] string[] stringArray, int size);
// Declares a managed prototype for an array of structures with integers.
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int TestArrayOfStructs(
[In, Out] MyPoint[] pointArray, int size);
// Declares a managed prototype for an array of structures with strings.
[DllImport("..\\LIB\\PinvokeLib.dll", CallingConvention = CallingConvention.Cdecl)]
internal static extern int TestArrayOfStructs2(
[In, Out] MyPerson[] personArray, int size);
}
' Declares a managed structure for each unmanaged structure.
<StructLayout(LayoutKind.Sequential)>
Public Structure MyPoint
Public x As Integer
Public y As Integer
Public Sub New(x As Integer, y As Integer)
Me.x = x
Me.y = y
End Sub
End Structure
<StructLayout(LayoutKind.Sequential, CharSet:=CharSet.Ansi)>
Public Structure MyPerson
Public first As String
Public last As String
Public Sub New(first As String, last As String)
Me.first = first
Me.last = last
End Sub
End Structure
Friend Class NativeMethods
' Declares a managed prototype for an array of integers by value.
' The array size cannot be changed, but the array is copied back.
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Function TestArrayOfInts(
<[In], Out> ByVal myArray() As Integer, ByVal size As Integer) _
As Integer
End Function
' Declares managed prototype for an array of integers by reference.
' The array size can change, but the array is not copied back
' automatically because the marshaler does not know the resulting size.
' The copy must be performed manually.
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Function TestRefArrayOfInts(
ByRef myArray As IntPtr, ByRef size As Integer) As Integer
End Function
' Declares a managed prototype for a matrix of integers by value.
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Function TestMatrixOfInts(
<[In], Out> ByVal matrix(,) As Integer, ByVal row As Integer) _
As Integer
End Function
' Declares a managed prototype for an array of strings by value.
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Function TestArrayOfStrings(
<[In], Out> ByVal strArray() As String, ByVal size As Integer) _
As Integer
End Function
' Declares a managed prototype for an array of structures with
' integers.
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Function TestArrayOfStructs(
<[In], Out> ByVal pointArray() As MyPoint, ByVal size As Integer) _
As Integer
End Function
' Declares a managed prototype for an array of structures with strings.
<DllImport("..\LIB\PinvokeLib.dll", CallingConvention:=CallingConvention.Cdecl)>
Friend Shared Function TestArrayOfStructs2(
<[In], Out> ByVal personArray() As MyPerson, ByVal size As Integer) _
As Integer
End Function
End Class
İşlevleri Çağırma
public class App
{
public static void Main()
{
// array ByVal
int[] array1 = new int[10];
Console.WriteLine("Integer array passed ByVal before call:");
for (int i = 0; i < array1.Length; i++)
{
array1[i] = i;
Console.Write(" " + array1[i]);
}
int sum1 = NativeMethods.TestArrayOfInts(array1, array1.Length);
Console.WriteLine("\nSum of elements:" + sum1);
Console.WriteLine("\nInteger array passed ByVal after call:");
foreach (int i in array1)
{
Console.Write(" " + i);
}
// array ByRef
int[] array2 = new int[10];
int size = array2.Length;
Console.WriteLine("\n\nInteger array passed ByRef before call:");
for (int i = 0; i < array2.Length; i++)
{
array2[i] = i;
Console.Write(" " + array2[i]);
}
IntPtr buffer = Marshal.AllocCoTaskMem(Marshal.SizeOf(size)
* array2.Length);
Marshal.Copy(array2, 0, buffer, array2.Length);
int sum2 = NativeMethods.TestRefArrayOfInts(ref buffer, ref size);
Console.WriteLine("\nSum of elements:" + sum2);
if (size > 0)
{
int[] arrayRes = new int[size];
Marshal.Copy(buffer, arrayRes, 0, size);
Marshal.FreeCoTaskMem(buffer);
Console.WriteLine("\nInteger array passed ByRef after call:");
foreach (int i in arrayRes)
{
Console.Write(" " + i);
}
}
else
{
Console.WriteLine("\nArray after call is empty");
}
// matrix ByVal
const int DIM = 5;
int[,] matrix = new int[DIM, DIM];
Console.WriteLine("\n\nMatrix before call:");
for (int i = 0; i < DIM; i++)
{
for (int j = 0; j < DIM; j++)
{
matrix[i, j] = j;
Console.Write(" " + matrix[i, j]);
}
Console.WriteLine("");
}
int sum3 = NativeMethods.TestMatrixOfInts(matrix, DIM);
Console.WriteLine("\nSum of elements:" + sum3);
Console.WriteLine("\nMatrix after call:");
for (int i = 0; i < DIM; i++)
{
for (int j = 0; j < DIM; j++)
{
Console.Write(" " + matrix[i, j]);
}
Console.WriteLine("");
}
// string array ByVal
string[] strArray = { "one", "two", "three", "four", "five" };
Console.WriteLine("\n\nstring array before call:");
foreach (string s in strArray)
{
Console.Write(" " + s);
}
int lenSum = NativeMethods.TestArrayOfstrings(strArray, strArray.Length);
Console.WriteLine("\nSum of string lengths:" + lenSum);
Console.WriteLine("\nstring array after call:");
foreach (string s in strArray)
{
Console.Write(" " + s);
}
// struct array ByVal
MyPoint[] points = { new MyPoint(1, 1), new MyPoint(2, 2), new MyPoint(3, 3) };
Console.WriteLine("\n\nPoints array before call:");
foreach (MyPoint p in points)
{
Console.WriteLine($"X = {p.X}, Y = {p.Y}");
}
int allSum = NativeMethods.TestArrayOfStructs(points, points.Length);
Console.WriteLine("\nSum of points:" + allSum);
Console.WriteLine("\nPoints array after call:");
foreach (MyPoint p in points)
{
Console.WriteLine($"X = {p.X}, Y = {p.Y}");
}
// struct with strings array ByVal
MyPerson[] persons =
{
new MyPerson("Kim", "Akers"),
new MyPerson("Adam", "Barr"),
new MyPerson("Jo", "Brown")
};
Console.WriteLine("\n\nPersons array before call:");
foreach (MyPerson pe in persons)
{
Console.WriteLine($"First = {pe.First}, Last = {pe.Last}");
}
int namesSum = NativeMethods.TestArrayOfStructs2(persons, persons.Length);
Console.WriteLine("\nSum of name lengths:" + namesSum);
Console.WriteLine("\n\nPersons array after call:");
foreach (MyPerson pe in persons)
{
Console.WriteLine($"First = {pe.First}, Last = {pe.Last}");
}
}
}
Public Class App
Public Shared Sub Main()
' array ByVal
Dim array1(9) As Integer
Console.WriteLine("Integer array passed ByVal before call:")
Dim i As Integer
For i = 0 To array1.Length - 1
array1(i) = i
Console.Write(" " & array1(i))
Next i
Dim sum1 As Integer = NativeMethods.TestArrayOfInts(array1, array1.Length)
Console.WriteLine(ControlChars.CrLf & "Sum of elements:" & sum1)
Console.WriteLine(ControlChars.CrLf & "Integer array passed ByVal after call:")
For Each i In array1
Console.Write(" " & i)
Next i
' array ByRef
Dim array2(9) As Integer
Dim arraySize As Integer = array2.Length
Console.WriteLine(ControlChars.CrLf & ControlChars.CrLf &
"Integer array passed ByRef before call:")
For i = 0 To array2.Length - 1
array2(i) = i
Console.Write(" " & array2(i))
Next i
Dim buffer As IntPtr = Marshal.AllocCoTaskMem(Marshal.SizeOf(
arraySize) * array2.Length)
Marshal.Copy(array2, 0, buffer, array2.Length)
Dim sum2 As Integer = NativeMethods.TestRefArrayOfInts(buffer,
arraySize)
Console.WriteLine(ControlChars.CrLf & "Sum of elements:" & sum2)
If arraySize > 0 Then
Dim arrayRes(arraySize - 1) As Integer
Marshal.Copy(buffer, arrayRes, 0, arraySize)
Marshal.FreeCoTaskMem(buffer)
Console.WriteLine(ControlChars.CrLf & "Integer array passed ByRef after call:")
For Each i In arrayRes
Console.Write(" " & i)
Next i
Else
Console.WriteLine(ControlChars.CrLf & "Array after call is empty")
End If
' matrix ByVal
Const [DIM] As Integer = 4
Dim matrix([DIM], [DIM]) As Integer
Console.WriteLine(ControlChars.CrLf & ControlChars.CrLf &
"Matrix before call:")
For i = 0 To [DIM]
Dim j As Integer
For j = 0 To [DIM]
matrix(i, j) = j
Console.Write(" " & matrix(i, j))
Next j
Console.WriteLine("")
Next i
Dim sum3 As Integer = NativeMethods.TestMatrixOfInts(matrix, [DIM] + 1)
Console.WriteLine(ControlChars.CrLf & "Sum of elements:" & sum3)
Console.WriteLine(ControlChars.CrLf & "Matrix after call:")
For i = 0 To [DIM]
Dim j As Integer
For j = 0 To [DIM]
Console.Write(" " & matrix(i, j))
Next j
Console.WriteLine("")
Next i
' string array ByVal
Dim strArray As String() = {"one", "two", "three", "four",
"five"}
Console.WriteLine(ControlChars.CrLf & ControlChars.CrLf &
"String array before call:")
Dim s As String
For Each s In strArray
Console.Write(" " & s)
Next s
Dim lenSum As Integer = NativeMethods.TestArrayOfStrings(
strArray, strArray.Length)
Console.WriteLine(ControlChars.CrLf &
"Sum of string lengths:" & lenSum)
Console.WriteLine(ControlChars.CrLf & "String array after call:")
For Each s In strArray
Console.Write(" " & s)
Next s
' struct array ByVal
Dim points As MyPoint() = {New MyPoint(1, 1), New MyPoint(2, 2),
New MyPoint(3, 3)}
Console.WriteLine(ControlChars.CrLf & ControlChars.CrLf &
"Points array before call:")
Dim p As MyPoint
For Each p In points
Console.WriteLine($"x = {p.x}, y = {p.y}")
Next p
Dim allSum As Integer = NativeMethods.TestArrayOfStructs(points,
points.Length)
Console.WriteLine(ControlChars.CrLf & "Sum of points:" & allSum)
Console.WriteLine(ControlChars.CrLf & "Points array after call:")
For Each p In points
Console.WriteLine($"x = {p.x}, y = {p.y}")
Next p
' struct with strings array ByVal
Dim persons As MyPerson() = {New MyPerson("Kim", "Akers"),
New MyPerson("Adam", "Barr"),
New MyPerson("Jo", "Brown")}
Console.WriteLine(ControlChars.CrLf & ControlChars.CrLf &
"Persons array before call:")
Dim pe As MyPerson
For Each pe In persons
Console.WriteLine($"first = {pe.first}, last = {pe.last}")
Next pe
Dim namesSum As Integer = NativeMethods.TestArrayOfStructs2(persons,
persons.Length)
Console.WriteLine(ControlChars.CrLf & "Sum of name lengths:" &
namesSum)
Console.WriteLine(ControlChars.CrLf & ControlChars.CrLf _
& "Persons array after call:")
For Each pe In persons
Console.WriteLine($"first = {pe.first}, last = {pe.last}")
Next pe
End Sub
End Class