Exemplo de estruturas
Este exemplo demonstra como passar uma estrutura que aponta para uma segunda estrutura, passe uma estrutura com uma estrutura incorporada e passar uma estrutura com uma matriz incorporada.
O código-fonte para os exemplos de código a seguir é fornecido pelo.NET estrutura Invocação de plataforma Tecnologia Exemplo.
O exemplo de estruturas utiliza as seguintes funções não gerenciadas, mostradas com sua declaração de função original:
TestStructInStruct exportados de PinvokeLib.dll.
int TestStructInStruct(MYPERSON2* pPerson2);
TestStructInStruct3 exportados de PinvokeLib.dll.
void TestStructInStruct3(MYPERSON3 person3);
TestArrayInStruct exportados de PinvokeLib.dll.
void TestArrayInStruct( MYARRAYSTRUCT* pStruct );
PinvokeLib.dll é uma biblioteca de não gerenciada personalizada que contém implementações de quatro estruturas e funções listadas anteriormente: MYPERSON, MYPERSON2, MYPERSON3, and MYARRAYSTRUCT.Essas estruturas de contenham os seguintes elementos:
typedef struct _MYPERSON
{
char* first;
char* last;
} MYPERSON, *LP_MYPERSON;
typedef struct _MYPERSON2
{
MYPERSON* person;
int age;
} MYPERSON2, *LP_MYPERSON2;
typedef struct _MYPERSON3
{
MYPERSON person;
int age;
} MYPERSON3;
typedef struct _MYARRAYSTRUCT
{
bool flag;
int vals[ 3 ];
} MYARRAYSTRUCT;
O gerenciadoMyPerson, MyPerson2, MyPerson3, e MyArrayStruct estruturas têm a característica do seguinte:
MyPerson contém somente os membros da seqüência de caracteres. The Conjunto de caracteres campo define as seqüências de caracteres de formato ANSI quando transmitido para a função não gerenciada.
MyPerson2 contém um IntPtr to the MyPerson estrutura. The IntPtr tipo substitui o ponteiro original para a estrutura não gerenciada como aplicativos do .NET Framework não usam ponteiros, a menos que o código está marcado como não seguro.
MyPerson3 contém MyPerson sistema autônomo uma estrutura incorporada. Uma estrutura incorporada em outra estrutura pode ser achatada colocando sistema autônomo elementos da estrutura incorporado diretamente para a estrutura principal ou deixá-lo sistema autônomo uma estrutura incorporada, sistema autônomo é concluído neste exemplo.
MyArrayStruct contém uma matriz de inteiros. The MarshalAsAttribute Define o atributo de UnmanagedType valor de enumeração para ByValArray, que é usado para indicar o número de elementos na matriz.
Para todas as estruturas neste exemplo, a StructLayoutAttribute o atributo é aplicado a garantir que os membros são organizados em memória seqüencialmente, na ordem em que aparecem.
The LibWrap classe contém protótipos gerenciado para o TestStructInStruct, TestStructInStruct3, e TestArrayInStruct os métodos chamados App classe. Cada protótipo declara um único parâmetro, da seguinte maneira:
TestStructInStruct declara uma referência ao tipo MyPerson2 sistema autônomo seu parâmetro.
TestStructInStruct3 declara tipo MyPerson3 sistema autônomo seu parâmetro e passa o parâmetro por valor.
TestArrayInStruct declara uma referência ao tipo MyArrayStruct sistema autônomo seu parâmetro.
Estruturas sistema autônomo argumentos para métodos são passadas por valor, a menos que o parâmetro contém o ref (ByRefpalavra-chave no Visual Basic).Por exemplo, a TestStructInStruct método passa uma referência (o valor de um endereço) para um objeto do tipo MyPerson2 para código não gerenciado. Para manipular a estrutura que MyPerson2 pontos, o exemplo cria um buffer de dimensionar especificado e retorna seu endereço combinando o Marshal.AllocCoTaskMem e Marshal.SizeOf métodos. Em seguida, o exemplo copia o conteúdo da estrutura gerenciada para o buffer não-gerenciado.Finalmente, o exemplo usa o Marshal.PtrToStructure método para realizar realizar marshaling dados do buffer não-gerenciado em um objeto gerenciado e o Marshal.FreeCoTaskMem método para liberar o bloco não gerenciado de memória.
Declaração de protótipos
' Declares a managed structure for each unmanaged structure.
< StructLayout( LayoutKind.Sequential, CharSet := CharSet.Ansi )> _
Public Structure MyPerson
Public first As String
Public last As String
End Structure 'MyPerson
< StructLayout( LayoutKind.Sequential )> _
Public Structure MyPerson2
Public person As IntPtr
Public age As Integer
End Structure 'MyPerson2
< StructLayout( LayoutKind.Sequential )> _
Public Structure MyPerson3
Public person As MyPerson
Public age As Integer
End Structure 'MyPerson3
< StructLayout( LayoutKind.Sequential )> _
Public Structure MyArrayStruct
Public flag As Boolean
< MarshalAs( UnmanagedType.ByValArray, SizeConst:=3 )> _
Public vals As Integer()
End Structure 'MyArrayStruct
Public Class LibWrap
' Declares managed prototypes for unmanaged functions.
Declare Function TestStructInStruct Lib "..\LIB\PinvokeLib.dll" ( _
ByRef person2 As MyPerson2 ) As Integer
Declare Function TestStructInStruct3 Lib "..\LIB\PinvokeLib.dll" ( _
ByVal person3 As MyPerson3 ) As Integer
Declare Function TestArrayInStruct Lib "..\LIB\PinvokeLib.dll" ( _
ByRef myStruct As MyArrayStruct ) As Integer
End Class 'LibWrap
// Declares a managed structure for each unmanaged structure.
[ StructLayout( LayoutKind.Sequential, CharSet=CharSet.Ansi )]
public struct MyPerson
{
public String first;
public String last;
}
[ StructLayout( LayoutKind.Sequential )]
public struct MyPerson2
{
public IntPtr person;
public int age;
}
[ StructLayout( LayoutKind.Sequential )]
public struct MyPerson3
{
public MyPerson person;
public int age;
}
[ StructLayout( LayoutKind.Sequential )]
public struct MyArrayStruct
{
public bool flag;
[ MarshalAs( UnmanagedType.ByValArray, SizeConst=3 )]
public int[] vals;
}
public class LibWrap
{
// Declares a managed prototype for unmanaged function.
[ DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern int TestStructInStruct( ref MyPerson2 person2 );
[ DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern int TestStructInStruct3( MyPerson3 person3 );
[ DllImport( "..\\LIB\\PinvokeLib.dll" )]
public static extern int TestArrayInStruct( ref MyArrayStruct
myStruct );
}
Chamando funções
Public Class App
Public Shared Sub Main()
' Structure with a pointer to another structure.
Dim personName As MyPerson
personName.first = "Mark"
personName.last = "Lee"
Dim personAll As MyPerson2
personAll.age = 30
Dim buffer As IntPtr = Marshal.AllocCoTaskMem( Marshal.SizeOf( _
personName ))
Marshal.StructureToPtr( personName, buffer, False )
personAll.person = buffer
Console.WriteLine( ControlChars.CrLf & "Person before call:" )
Console.WriteLine( "first = {0}, last = {1}, age = {2}", _
personName.first, personName.last, personAll.age )
Dim res As Integer = LibWrap.TestStructInStruct( personAll )
Dim personRes As MyPerson = _
CType( Marshal.PtrToStructure( personAll.person, _
GetType( MyPerson )), MyPerson )
Marshal.FreeCoTaskMem( buffer )
Console.WriteLine( "Person after call:" )
Console.WriteLine( "first = {0}, last = {1}, age = {2}", _
personRes.first, _
personRes.last, personAll.age )
' Structure with an embedded structure.
Dim person3 As New MyPerson3()
person3.person.first = "John"
person3.person.last = "Evens"
person3.age = 27
LibWrap.TestStructInStruct3( person3 )
' Structure with an embedded array.
Dim myStruct As New MyArrayStruct()
myStruct.flag = False
Dim array( 2 ) As Integer
myStruct.vals = array
myStruct.vals( 0 ) = 1
myStruct.vals( 1 ) = 4
myStruct.vals( 2 ) = 9
Console.WriteLine( ControlChars.CrLf & "Structure with array _
before call:" )
Console.WriteLine( myStruct.flag )
Console.WriteLine( "{0} {1} {2}", myStruct.vals( 0 ), _
myStruct.vals( 1 ), myStruct.vals( 2 ) )
LibWrap.TestArrayInStruct( myStruct )
Console.WriteLine( ControlChars.CrLf & "Structure with array _
after call:" )
Console.WriteLine( myStruct.flag )
Console.WriteLine( "{0} {1} {2}", myStruct.vals( 0 ), _
myStruct.vals( 1 ), myStruct.vals( 2 ) )
End Sub 'Main
End Class 'App
public class App
{
public static void Main()
{
// Structure with a pointer to another structure.
MyPerson personName;
personName.first = "Mark";
personName.last = "Lee";
MyPerson2 personAll;
personAll.age = 30;
IntPtr buffer = Marshal.AllocCoTaskMem( Marshal.SizeOf(
personName ));
Marshal.StructureToPtr( personName, buffer, false );
personAll.person = buffer;
Console.WriteLine( "\nPerson before call:" );
Console.WriteLine( "first = {0}, last = {1}, age = {2}",
personName.first, personName.last, personAll.age );
int res = LibWrap.TestStructInStruct( ref personAll );
MyPerson personRes =
(MyPerson)Marshal.PtrToStructure( personAll.person,
typeof( MyPerson ));
Marshal.FreeCoTaskMem( buffer );
Console.WriteLine( "Person after call:" );
Console.WriteLine( "first = {0}, last = {1}, age = {2}",
personRes.first, personRes.last, personAll.age );
// Structure with an embedded structure.
MyPerson3 person3 = new MyPerson3();
person3.person.first = "John";
person3.person.last = "Evens";
person3.age = 27;
LibWrap.TestStructInStruct3( person3 );
// Structure with an embedded array.
MyArrayStruct myStruct = new MyArrayStruct();
myStruct.flag = false;
myStruct.vals = new int[ 3 ];
myStruct.vals[ 0 ] = 1;
myStruct.vals[ 1 ] = 4;
myStruct.vals[ 2 ] = 9;
Console.WriteLine( "\nStructure with array before call:" );
Console.WriteLine( myStruct.flag );
Console.WriteLine( "{0} {1} {2}", myStruct.vals[ 0 ],
myStruct.vals[ 1 ], myStruct.vals[ 2 ] );
LibWrap.TestArrayInStruct( ref myStruct );
Console.WriteLine( "\nStructure with array after call:" );
Console.WriteLine( myStruct.flag );
Console.WriteLine( "{0} {1} {2}", myStruct.vals[ 0 ],
myStruct.vals[ 1 ], myStruct.vals[ 2 ] );
}
}
Consulte também
Conceitos
marshaling de classes, estruturas e uniões