Aracılığıyla paylaş


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 MyPointMyPerson 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

Ayrıca bkz.