Freigeben über


TypeBuilder.DefinePInvokeMethod Methode

Definition

Definiert eine PInvoke-Methode.

Überlädt

DefinePInvokeMethod(String, String, MethodAttributes, CallingConventions, Type, Type[], CallingConvention, CharSet)

Definiert eine PInvoke-Methode anhand der Angaben für den Namen, den Namen der DLL, in der die Methode definiert ist, für die Attribute der Methode, die Aufrufkonvention der Methode, den Rückgabetyp der Methode, die Parametertypen der Methode und die PInvoke-Flags.

DefinePInvokeMethod(String, String, String, MethodAttributes, CallingConventions, Type, Type[], CallingConvention, CharSet)

Definiert eine PInvoke-Methode anhand der Angaben für den Namen, den Namen der DLL, in der die Methode definiert ist, für den Namen des Einstiegspunkts, die Attribute der Methode, die Aufrufkonvention der Methode, den Rückgabetyp der Methode, die Parametertypen der Methode und die PInvoke-Flags.

DefinePInvokeMethod(String, String, String, MethodAttributes, CallingConventions, Type, Type[], Type[], Type[], Type[][], Type[][], CallingConvention, CharSet)

Definiert eine PInvoke-Methode anhand der Angaben für den Namen, den Namen der DLL, in der die Methode definiert ist, den Namen des Einstiegspunkts, die Attribute der Methode, die Aufrufkonvention der Methode, den Rückgabetyp der Methode, die Parametertypen der Methode, die PInvoke-Flags, die benutzerdefinierten Modifizierer für die Parameter und den Rückgabetyp.

DefinePInvokeMethod(String, String, MethodAttributes, CallingConventions, Type, Type[], CallingConvention, CharSet)

Quelle:
TypeBuilder.cs
Quelle:
TypeBuilder.cs
Quelle:
TypeBuilder.cs

Definiert eine PInvoke-Methode anhand der Angaben für den Namen, den Namen der DLL, in der die Methode definiert ist, für die Attribute der Methode, die Aufrufkonvention der Methode, den Rückgabetyp der Methode, die Parametertypen der Methode und die PInvoke-Flags.

public:
 System::Reflection::Emit::MethodBuilder ^ DefinePInvokeMethod(System::String ^ name, System::String ^ dllName, System::Reflection::MethodAttributes attributes, System::Reflection::CallingConventions callingConvention, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, System::Runtime::InteropServices::CallingConvention nativeCallConv, System::Runtime::InteropServices::CharSet nativeCharSet);
public System.Reflection.Emit.MethodBuilder DefinePInvokeMethod (string name, string dllName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet);
public System.Reflection.Emit.MethodBuilder DefinePInvokeMethod (string name, string dllName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type returnType, Type[] parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet);
member this.DefinePInvokeMethod : string * string * System.Reflection.MethodAttributes * System.Reflection.CallingConventions * Type * Type[] * System.Runtime.InteropServices.CallingConvention * System.Runtime.InteropServices.CharSet -> System.Reflection.Emit.MethodBuilder
Public Function DefinePInvokeMethod (name As String, dllName As String, attributes As MethodAttributes, callingConvention As CallingConventions, returnType As Type, parameterTypes As Type(), nativeCallConv As CallingConvention, nativeCharSet As CharSet) As MethodBuilder

Parameter

name
String

Der Name der PInvoke-Methode. name darf keine eingebetteten NULL-Werte enthalten.

dllName
String

Der Name der DLL, in der die PInvoke-Methode definiert ist.

attributes
MethodAttributes

Die Attribute der Methode.

callingConvention
CallingConventions

Die Aufrufkonvention der Methode.

returnType
Type

Der Rückgabetyp der Methode.

parameterTypes
Type[]

Die Typen der Parameter der Methode.

nativeCallConv
CallingConvention

Die systemeigene Aufrufkonvention.

nativeCharSet
CharSet

Der systemeigene Zeichensatz der Methode.

Gibt zurück

Die definierte PInvoke-Methode.

Ausnahmen

Die Methode ist nicht statisch.

- oder -

Der übergeordnete Typ ist eine Schnittstelle.

- oder -

Die Methode ist abstrakt.

- oder -

Die Methode wurde bereits definiert.

- oder -

Die Länge von name oder dllName ist 0 (null).

name oder dllName ist null.

Der enthaltende Typ wurde zuvor mit CreateType() erstellt.

Beispiele

Im folgenden Beispiel wird veranschaulicht, wie Sie die DefinePInvokeMethod -Methode verwenden, um eine PInvoke -Methode zu erstellen, und wie Sie das MethodImplAttributes.PreserveSig Flag den Methodenimplementierungsflags hinzufügen, nachdem Sie die MethodBuilder- und MethodBuilder.SetImplementationFlags -MethodBuilder.GetMethodImplementationFlagsMethode erstellt haben.

Wichtig

Um einen Rückgabewert ungleich Null zu erhalten, müssen Sie das MethodImplAttributes.PreserveSig Flag hinzufügen.

Im Beispiel wird eine dynamische Assembly mit einem dynamischen Modul und einem einzelnen Typ erstellt, MyTypeder die PInvoke -Methode enthält. Die PInvoke -Methode stellt die Win32-Funktion GetTickCount dar.

Wenn das Beispiel ausgeführt wird, wird die PInvoke -Methode ausgeführt. Außerdem wird die dynamische Assembly als PInvokeTest.dll gespeichert. Sie können den Ildasm.exe (IL Disassembler) verwenden, um die MyType Klasse und die static darin enthaltene Methode (Shared in Visual Basic) PInvoke zu untersuchen. Sie können ein Visual Basic- oder C#-Programm kompilieren, das die statische MyType.GetTickCount Methode verwendet, /r:PInvokeTest.dllindem Sie einen Verweis auf die DLL einschließen, wenn Sie csc.exe oder vbc.exe ausführen, z. B. .

using namespace System;
using namespace System::Text;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
using namespace System::Runtime::InteropServices;

    void main()
    {
        // Create the AssemblyBuilder.
        AssemblyName^ asmName = gcnew AssemblyName("PInvokeTest");
        AssemblyBuilder^ dynamicAsm = AppDomain::CurrentDomain->DefineDynamicAssembly(
            asmName, 
            AssemblyBuilderAccess::RunAndSave
        );

        // Create the module.
        ModuleBuilder^ dynamicMod = 
            dynamicAsm->DefineDynamicModule(asmName->Name, asmName->Name + ".dll");

        // Create the TypeBuilder for the class that will contain the 
        // signature for the PInvoke call.
        TypeBuilder^ tb = dynamicMod->DefineType(
            "MyType", 
            TypeAttributes::Public | TypeAttributes::UnicodeClass
        );
    
        MethodBuilder^ mb = tb->DefinePInvokeMethod(
            "GetTickCount",
            "Kernel32.dll",
            MethodAttributes::Public | MethodAttributes::Static | MethodAttributes::PinvokeImpl,
            CallingConventions::Standard,
            int::typeid,
            Type::EmptyTypes,
            CallingConvention::Winapi,
            CharSet::Ansi);

        // Add PreserveSig to the method implementation flags. NOTE: If this line
        // is commented out, the return value will be zero when the method is
        // invoked.
        mb->SetImplementationFlags(
            mb->GetMethodImplementationFlags() | MethodImplAttributes::PreserveSig);

        // The PInvoke method does not have a method body. 

        // Create the class and test the method.
        Type^ t = tb->CreateType();

        MethodInfo^ mi = t->GetMethod("GetTickCount");
        Console::WriteLine("Testing PInvoke method...");
        Console::WriteLine("GetTickCount returned: {0}", mi->Invoke(nullptr, nullptr));

        // Produce the .dll file.
        Console::WriteLine("Saving: " + asmName->Name + ".dll");
        dynamicAsm->Save(asmName->Name + ".dll");
    };

/* This example produces output similar to the following:

Testing PInvoke method...
GetTickCount returned: 1314410994
Saving: PInvokeTest.dll
 */
using System;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;

public class Example
{
    public static void Main()
    {
        // Create the AssemblyBuilder.
        AssemblyName asmName = new AssemblyName("PInvokeTest");
        AssemblyBuilder dynamicAsm = AppDomain.CurrentDomain.DefineDynamicAssembly(
            asmName,
            AssemblyBuilderAccess.RunAndSave
        );

        // Create the module.
        ModuleBuilder dynamicMod =
            dynamicAsm.DefineDynamicModule(asmName.Name, asmName.Name + ".dll");

        // Create the TypeBuilder for the class that will contain the
        // signature for the PInvoke call.
        TypeBuilder tb = dynamicMod.DefineType(
            "MyType",
            TypeAttributes.Public | TypeAttributes.UnicodeClass
        );

        MethodBuilder mb = tb.DefinePInvokeMethod(
            "GetTickCount",
            "Kernel32.dll",
            MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl,
            CallingConventions.Standard,
            typeof(int),
            Type.EmptyTypes,
            CallingConvention.Winapi,
            CharSet.Ansi);

        // Add PreserveSig to the method implementation flags. NOTE: If this line
        // is commented out, the return value will be zero when the method is
        // invoked.
        mb.SetImplementationFlags(
            mb.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig);

        // The PInvoke method does not have a method body.

        // Create the class and test the method.
        Type t = tb.CreateType();

        MethodInfo mi = t.GetMethod("GetTickCount");
        Console.WriteLine("Testing PInvoke method...");
        Console.WriteLine("GetTickCount returned: {0}", mi.Invoke(null, null));

        // Produce the .dll file.
        Console.WriteLine("Saving: " + asmName.Name + ".dll");
        dynamicAsm.Save(asmName.Name + ".dll");
    }
}

/* This example produces output similar to the following:

Testing PInvoke method...
GetTickCount returned: 1312576235
Saving: PInvokeTest.dll
 */
Imports System.Text
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Runtime.InteropServices

Public Class Example
    
    Public Shared Sub Main() 
        
        ' Create the AssemblyBuilder.
        Dim asmName As New AssemblyName("PInvokeTest")
        Dim dynamicAsm As AssemblyBuilder = _
            AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, _
                AssemblyBuilderAccess.RunAndSave)
        
        ' Create the module.
        Dim dynamicMod As ModuleBuilder = _
            dynamicAsm.DefineDynamicModule(asmName.Name, asmName.Name & ".dll")
        
        ' Create the TypeBuilder for the class that will contain the 
        ' signature for the PInvoke call.
        Dim tb As TypeBuilder = dynamicMod.DefineType("MyType", _
            TypeAttributes.Public Or TypeAttributes.UnicodeClass)
        
        Dim mb As MethodBuilder = tb.DefinePInvokeMethod( _
            "GetTickCount", _
            "Kernel32.dll", _
            MethodAttributes.Public Or MethodAttributes.Static Or MethodAttributes.PinvokeImpl, _
            CallingConventions.Standard, _
            GetType(Integer), _
            Type.EmptyTypes, _
            CallingConvention.Winapi, _
            CharSet.Ansi)

        ' Add PreserveSig to the method implementation flags. NOTE: If this line
        ' is commented out, the return value will be zero when the method is
        ' invoked.
        mb.SetImplementationFlags( _
            mb.GetMethodImplementationFlags() Or MethodImplAttributes.PreserveSig)
        
        ' The PInvoke method does not have a method body.
        
        ' Create the class and test the method.
        Dim t As Type = tb.CreateType()

        Dim mi As MethodInfo = t.GetMethod("GetTickCount")
        Console.WriteLine("Testing PInvoke method...")
        Console.WriteLine("GetTickCount returned: {0}", mi.Invoke(Nothing, Nothing))

        ' Produce the .dll file.
        Console.WriteLine("Saving: " & asmName.Name & ".dll")
        dynamicAsm.Save(asmName.Name & ".dll")
    
    End Sub  
End Class 

' This example produces output similar to the following:
'
'Testing PInvoke method...
'GetTickCount returned: 1313078714
'Saving: PInvokeTest.dll

Hinweise

Einige DLL-Importattribute (siehe Beschreibung von DllImportAttribute) können nicht als Argumente für diese Methode angegeben werden. Beispielsweise muss das DLL-Import-Attribut MethodImplAttributes.PreserveSig hinzugefügt werden, nachdem die PInvoke Methode erstellt wurde, wenn die Methode einen Wert zurückgibt. Das Beispiel zeigt, wie dies geschieht.

Gilt für:

DefinePInvokeMethod(String, String, String, MethodAttributes, CallingConventions, Type, Type[], CallingConvention, CharSet)

Quelle:
TypeBuilder.cs
Quelle:
TypeBuilder.cs
Quelle:
TypeBuilder.cs

Definiert eine PInvoke-Methode anhand der Angaben für den Namen, den Namen der DLL, in der die Methode definiert ist, für den Namen des Einstiegspunkts, die Attribute der Methode, die Aufrufkonvention der Methode, den Rückgabetyp der Methode, die Parametertypen der Methode und die PInvoke-Flags.

public:
 System::Reflection::Emit::MethodBuilder ^ DefinePInvokeMethod(System::String ^ name, System::String ^ dllName, System::String ^ entryName, System::Reflection::MethodAttributes attributes, System::Reflection::CallingConventions callingConvention, Type ^ returnType, cli::array <Type ^> ^ parameterTypes, System::Runtime::InteropServices::CallingConvention nativeCallConv, System::Runtime::InteropServices::CharSet nativeCharSet);
public System.Reflection.Emit.MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type? returnType, Type[]? parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet);
public System.Reflection.Emit.MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type returnType, Type[] parameterTypes, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet);
member this.DefinePInvokeMethod : string * string * string * System.Reflection.MethodAttributes * System.Reflection.CallingConventions * Type * Type[] * System.Runtime.InteropServices.CallingConvention * System.Runtime.InteropServices.CharSet -> System.Reflection.Emit.MethodBuilder
Public Function DefinePInvokeMethod (name As String, dllName As String, entryName As String, attributes As MethodAttributes, callingConvention As CallingConventions, returnType As Type, parameterTypes As Type(), nativeCallConv As CallingConvention, nativeCharSet As CharSet) As MethodBuilder

Parameter

name
String

Der Name der PInvoke-Methode. name darf keine eingebetteten NULL-Werte enthalten.

dllName
String

Der Name der DLL, in der die PInvoke-Methode definiert ist.

entryName
String

Der Name des Einstiegspunkts in die DLL.

attributes
MethodAttributes

Die Attribute der Methode.

callingConvention
CallingConventions

Die Aufrufkonvention der Methode.

returnType
Type

Der Rückgabetyp der Methode.

parameterTypes
Type[]

Die Typen der Parameter der Methode.

nativeCallConv
CallingConvention

Die systemeigene Aufrufkonvention.

nativeCharSet
CharSet

Der systemeigene Zeichensatz der Methode.

Gibt zurück

Die definierte PInvoke-Methode.

Ausnahmen

Die Methode ist nicht statisch.

- oder -

Der übergeordnete Typ ist eine Schnittstelle.

- oder -

Die Methode ist abstrakt.

- oder -

Die Methode wurde bereits definiert.

- oder -

Die Länge von name, dllName oder entryName ist 0 (null).

name, dllName oder entryName ist null.

Der enthaltende Typ wurde zuvor mit CreateType() erstellt.

Beispiele

Im folgenden Codebeispiel wird veranschaulicht, wie Sie die DefinePInvokeMethod -Methode verwenden, um eine PInvoke -Methode zu erstellen, und wie Sie das MethodImplAttributes.PreserveSig Flag den Methodenimplementierungsflags hinzufügen, nachdem Sie die MethodBuilder- und MethodBuilder.SetImplementationFlags -MethodBuilder.GetMethodImplementationFlagsMethode erstellt haben.

Wichtig

Um einen Rückgabewert ungleich Null zu erhalten, müssen Sie das MethodImplAttributes.PreserveSig Flag hinzufügen.

Im Beispiel wird eine dynamische Assembly mit einem dynamischen Modul und einem einzelnen Typ erstellt, MyTypeder die PInvoke -Methode enthält. Die PInvoke -Methode stellt die Win32-Funktion GetTickCount dar.

Wenn das Beispiel ausgeführt wird, wird die PInvoke -Methode ausgeführt. Außerdem wird die dynamische Assembly als PInvokeTest.dll gespeichert. Sie können den Ildasm.exe (IL Disassembler) verwenden, um die MyType Klasse und die static darin enthaltene Methode (Shared in Visual Basic) PInvoke zu untersuchen. Sie können ein Visual Basic- oder C#-Programm kompilieren, das die statische MyType.GetTickCount Methode verwendet, /r:PInvokeTest.dllindem Sie einen Verweis auf die DLL einschließen, wenn Sie csc.exe oder vbc.exe ausführen, z. B. .

using namespace System;
using namespace System::Text;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
using namespace System::Runtime::InteropServices;

    void main()
    {
        // Create the AssemblyBuilder.
        AssemblyName^ asmName = gcnew AssemblyName("PInvokeTest");
        AssemblyBuilder^ dynamicAsm = AppDomain::CurrentDomain->DefineDynamicAssembly(
            asmName, 
            AssemblyBuilderAccess::RunAndSave
        );

        // Create the module.
        ModuleBuilder^ dynamicMod = 
            dynamicAsm->DefineDynamicModule(asmName->Name, asmName->Name + ".dll");

        // Create the TypeBuilder for the class that will contain the 
        // signature for the PInvoke call.
        TypeBuilder^ tb = dynamicMod->DefineType(
            "MyType", 
            TypeAttributes::Public | TypeAttributes::UnicodeClass
        );
    
        MethodBuilder^ mb = tb->DefinePInvokeMethod(
            "GetTickCount",
            "Kernel32.dll",
            MethodAttributes::Public | MethodAttributes::Static | MethodAttributes::PinvokeImpl,
            CallingConventions::Standard,
            int::typeid,
            Type::EmptyTypes,
            CallingConvention::Winapi,
            CharSet::Ansi);

        // Add PreserveSig to the method implementation flags. NOTE: If this line
        // is commented out, the return value will be zero when the method is
        // invoked.
        mb->SetImplementationFlags(
            mb->GetMethodImplementationFlags() | MethodImplAttributes::PreserveSig);

        // The PInvoke method does not have a method body. 

        // Create the class and test the method.
        Type^ t = tb->CreateType();

        MethodInfo^ mi = t->GetMethod("GetTickCount");
        Console::WriteLine("Testing PInvoke method...");
        Console::WriteLine("GetTickCount returned: {0}", mi->Invoke(nullptr, nullptr));

        // Produce the .dll file.
        Console::WriteLine("Saving: " + asmName->Name + ".dll");
        dynamicAsm->Save(asmName->Name + ".dll");
    };

/* This example produces output similar to the following:

Testing PInvoke method...
GetTickCount returned: 1314410994
Saving: PInvokeTest.dll
 */
using System;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;

public class Example
{
    public static void Main()
    {
        // Create the AssemblyBuilder.
        AssemblyName asmName = new AssemblyName("PInvokeTest");
        AssemblyBuilder dynamicAsm = AppDomain.CurrentDomain.DefineDynamicAssembly(
            asmName,
            AssemblyBuilderAccess.RunAndSave
        );

        // Create the module.
        ModuleBuilder dynamicMod =
            dynamicAsm.DefineDynamicModule(asmName.Name, asmName.Name + ".dll");

        // Create the TypeBuilder for the class that will contain the
        // signature for the PInvoke call.
        TypeBuilder tb = dynamicMod.DefineType(
            "MyType",
            TypeAttributes.Public | TypeAttributes.UnicodeClass
        );

        MethodBuilder mb = tb.DefinePInvokeMethod(
            "GetTickCount",
            "Kernel32.dll",
            MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl,
            CallingConventions.Standard,
            typeof(int),
            Type.EmptyTypes,
            CallingConvention.Winapi,
            CharSet.Ansi);

        // Add PreserveSig to the method implementation flags. NOTE: If this line
        // is commented out, the return value will be zero when the method is
        // invoked.
        mb.SetImplementationFlags(
            mb.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig);

        // The PInvoke method does not have a method body.

        // Create the class and test the method.
        Type t = tb.CreateType();

        MethodInfo mi = t.GetMethod("GetTickCount");
        Console.WriteLine("Testing PInvoke method...");
        Console.WriteLine("GetTickCount returned: {0}", mi.Invoke(null, null));

        // Produce the .dll file.
        Console.WriteLine("Saving: " + asmName.Name + ".dll");
        dynamicAsm.Save(asmName.Name + ".dll");
    }
}

/* This example produces output similar to the following:

Testing PInvoke method...
GetTickCount returned: 1312576235
Saving: PInvokeTest.dll
 */
Imports System.Text
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Runtime.InteropServices

Public Class Example
    
    Public Shared Sub Main() 
        
        ' Create the AssemblyBuilder.
        Dim asmName As New AssemblyName("PInvokeTest")
        Dim dynamicAsm As AssemblyBuilder = _
            AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, _
                AssemblyBuilderAccess.RunAndSave)
        
        ' Create the module.
        Dim dynamicMod As ModuleBuilder = _
            dynamicAsm.DefineDynamicModule(asmName.Name, asmName.Name & ".dll")
        
        ' Create the TypeBuilder for the class that will contain the 
        ' signature for the PInvoke call.
        Dim tb As TypeBuilder = dynamicMod.DefineType("MyType", _
            TypeAttributes.Public Or TypeAttributes.UnicodeClass)
        
        Dim mb As MethodBuilder = tb.DefinePInvokeMethod( _
            "GetTickCount", _
            "Kernel32.dll", _
            MethodAttributes.Public Or MethodAttributes.Static Or MethodAttributes.PinvokeImpl, _
            CallingConventions.Standard, _
            GetType(Integer), _
            Type.EmptyTypes, _
            CallingConvention.Winapi, _
            CharSet.Ansi)

        ' Add PreserveSig to the method implementation flags. NOTE: If this line
        ' is commented out, the return value will be zero when the method is
        ' invoked.
        mb.SetImplementationFlags( _
            mb.GetMethodImplementationFlags() Or MethodImplAttributes.PreserveSig)
        
        ' The PInvoke method does not have a method body.
        
        ' Create the class and test the method.
        Dim t As Type = tb.CreateType()

        Dim mi As MethodInfo = t.GetMethod("GetTickCount")
        Console.WriteLine("Testing PInvoke method...")
        Console.WriteLine("GetTickCount returned: {0}", mi.Invoke(Nothing, Nothing))

        ' Produce the .dll file.
        Console.WriteLine("Saving: " & asmName.Name & ".dll")
        dynamicAsm.Save(asmName.Name & ".dll")
    
    End Sub  
End Class 

' This example produces output similar to the following:
'
'Testing PInvoke method...
'GetTickCount returned: 1313078714
'Saving: PInvokeTest.dll

Hinweise

Einige DLL-Importattribute (siehe Beschreibung von DllImportAttribute) können nicht als Argumente für diese Methode angegeben werden. Beispielsweise muss das DLL-Import-Attribut MethodImplAttributes.PreserveSig hinzugefügt werden, nachdem die PInvoke Methode erstellt wurde, wenn die Methode einen Wert zurückgibt. Das Beispiel zeigt, wie dies geschieht.

Gilt für:

DefinePInvokeMethod(String, String, String, MethodAttributes, CallingConventions, Type, Type[], Type[], Type[], Type[][], Type[][], CallingConvention, CharSet)

Quelle:
TypeBuilder.cs
Quelle:
TypeBuilder.cs
Quelle:
TypeBuilder.cs

Definiert eine PInvoke-Methode anhand der Angaben für den Namen, den Namen der DLL, in der die Methode definiert ist, den Namen des Einstiegspunkts, die Attribute der Methode, die Aufrufkonvention der Methode, den Rückgabetyp der Methode, die Parametertypen der Methode, die PInvoke-Flags, die benutzerdefinierten Modifizierer für die Parameter und den Rückgabetyp.

public:
 System::Reflection::Emit::MethodBuilder ^ DefinePInvokeMethod(System::String ^ name, System::String ^ dllName, System::String ^ entryName, System::Reflection::MethodAttributes attributes, System::Reflection::CallingConventions callingConvention, Type ^ returnType, cli::array <Type ^> ^ returnTypeRequiredCustomModifiers, cli::array <Type ^> ^ returnTypeOptionalCustomModifiers, cli::array <Type ^> ^ parameterTypes, cli::array <cli::array <Type ^> ^> ^ parameterTypeRequiredCustomModifiers, cli::array <cli::array <Type ^> ^> ^ parameterTypeOptionalCustomModifiers, System::Runtime::InteropServices::CallingConvention nativeCallConv, System::Runtime::InteropServices::CharSet nativeCharSet);
public System.Reflection.Emit.MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type? returnType, Type[]? returnTypeRequiredCustomModifiers, Type[]? returnTypeOptionalCustomModifiers, Type[]? parameterTypes, Type[][]? parameterTypeRequiredCustomModifiers, Type[][]? parameterTypeOptionalCustomModifiers, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet);
public System.Reflection.Emit.MethodBuilder DefinePInvokeMethod (string name, string dllName, string entryName, System.Reflection.MethodAttributes attributes, System.Reflection.CallingConventions callingConvention, Type returnType, Type[] returnTypeRequiredCustomModifiers, Type[] returnTypeOptionalCustomModifiers, Type[] parameterTypes, Type[][] parameterTypeRequiredCustomModifiers, Type[][] parameterTypeOptionalCustomModifiers, System.Runtime.InteropServices.CallingConvention nativeCallConv, System.Runtime.InteropServices.CharSet nativeCharSet);
member this.DefinePInvokeMethod : string * string * string * System.Reflection.MethodAttributes * System.Reflection.CallingConventions * Type * Type[] * Type[] * Type[] * Type[][] * Type[][] * System.Runtime.InteropServices.CallingConvention * System.Runtime.InteropServices.CharSet -> System.Reflection.Emit.MethodBuilder
Public Function DefinePInvokeMethod (name As String, dllName As String, entryName As String, attributes As MethodAttributes, callingConvention As CallingConventions, returnType As Type, returnTypeRequiredCustomModifiers As Type(), returnTypeOptionalCustomModifiers As Type(), parameterTypes As Type(), parameterTypeRequiredCustomModifiers As Type()(), parameterTypeOptionalCustomModifiers As Type()(), nativeCallConv As CallingConvention, nativeCharSet As CharSet) As MethodBuilder

Parameter

name
String

Der Name der PInvoke-Methode. name darf keine eingebetteten NULL-Werte enthalten.

dllName
String

Der Name der DLL, in der die PInvoke-Methode definiert ist.

entryName
String

Der Name des Einstiegspunkts in die DLL.

attributes
MethodAttributes

Die Attribute der Methode.

callingConvention
CallingConventions

Die Aufrufkonvention der Methode.

returnType
Type

Der Rückgabetyp der Methode.

returnTypeRequiredCustomModifiers
Type[]

Ein Array von Typen, die die erforderlichen benutzerdefinierten Modifizierer, etwa IsConst, für den Rückgabetyp der Methode darstellen. Wenn der Rückgabetyp keine erforderlichen benutzerdefinierten Modifizierer hat, geben Sie nullan.

returnTypeOptionalCustomModifiers
Type[]

Ein Array von Typen, die die optionalen benutzerdefinierten Modifizierer, etwa IsConst, für den Rückgabetyp der Methode darstellen. Wenn der Rückgabetyp keine optionalen benutzerdefinierten Modifizierer hat, geben Sie null an.

parameterTypes
Type[]

Die Typen der Parameter der Methode.

parameterTypeRequiredCustomModifiers
Type[][]

Ein Array mit Arrays von Typen. Jedes Array von Typen stellt die erforderlichen benutzerdefinierten Modifizierer für den entsprechenden Parameter dar, z. B. IsConst. Wenn ein bestimmter Parameter keine erforderlichen benutzerdefinierten Modifizierer hat, geben Sie null anstelle eines Arrays von Typen an. Wenn keiner der Parameter erforderliche benutzerdefinierte Modifizierer hat, geben Sie null anstelle eines Arrays mit Arrays an.

parameterTypeOptionalCustomModifiers
Type[][]

Ein Array mit Arrays von Typen. Jedes Array von Typen stellt die optionalen benutzerdefinierten Modifizierer für den entsprechenden Parameter dar, z. B. IsConst. Wenn ein bestimmter Parameter keine optionalen benutzerdefinierten Modifizierer hat, geben Sie null anstelle eines Arrays von Typen an. Wenn keiner der Parameter optionale benutzerdefinierte Modifizierer hat, geben Sie null anstelle eines Arrays mit Arrays an.

nativeCallConv
CallingConvention

Die systemeigene Aufrufkonvention.

nativeCharSet
CharSet

Der systemeigene Zeichensatz der Methode.

Gibt zurück

Ein MethodBuilder, der die definierte PInvoke-Methode darstellt.

Ausnahmen

Die Methode ist nicht statisch.

- oder -

Der übergeordnete Typ ist eine Schnittstelle.

- oder -

Die Methode ist abstrakt.

- oder -

Die Methode wurde bereits definiert.

- oder -

Die Länge von name, dllName oder entryName ist 0 (null).

- oder -

Die Größe von parameterTypeRequiredCustomModifiers oder parameterTypeOptionalCustomModifiers entspricht nicht die Größe von parameterTypes.

name, dllName oder entryName ist null.

Der Typ wurde zuvor mit CreateType()erstellt.

- oder -

Für den aktuellen dynamischen Typ ist die IsGenericType-Eigenschaft true, aber die IsGenericTypeDefinition-Eigenschaft ist false.

Beispiele

Im folgenden Codebeispiel wird veranschaulicht, wie Sie die DefinePInvokeMethod -Methode verwenden, um eine PInvoke -Methode zu erstellen, und wie Sie das MethodImplAttributes.PreserveSig Flag den Methodenimplementierungsflags hinzufügen, nachdem Sie die MethodBuilder- und MethodBuilder.SetImplementationFlags -MethodBuilder.GetMethodImplementationFlagsMethode erstellt haben.

Im Beispiel wird eine dynamische Assembly mit einem dynamischen Modul und einem einzelnen Typ erstellt, MyTypeder die PInvoke -Methode enthält. Die PInvoke -Methode stellt die Win32-Funktion GetTickCount dar.

Wichtig

Um einen Rückgabewert ungleich Null zu erhalten, müssen Sie das MethodImplAttributes.PreserveSig Flag hinzufügen.

Hinweis

Im Beispiel wird eine Überladung verwendet, die keine benutzerdefinierten Modifizierer angibt. Um benutzerdefinierte Modifizierer anzugeben, ändern Sie den Beispielcode, um stattdessen diese Methodenüberladung zu verwenden.

Wenn das Beispiel ausgeführt wird, wird die PInvoke -Methode ausgeführt. Außerdem wird die dynamische Assembly als PInvokeTest.dll gespeichert. Sie können den Ildasm.exe (IL Disassembler) verwenden, um die MyType Klasse und die static darin enthaltene Methode (Shared in Visual Basic) PInvoke zu untersuchen. Sie können ein Visual Basic- oder C#-Programm kompilieren, das die statische MyType.GetTickCount Methode verwendet, /r:PInvokeTest.dllindem Sie einen Verweis auf die DLL einschließen, wenn Sie csc.exe oder vbc.exe ausführen, z. B. .

using namespace System;
using namespace System::Text;
using namespace System::Reflection;
using namespace System::Reflection::Emit;
using namespace System::Runtime::InteropServices;

    void main()
    {
        // Create the AssemblyBuilder.
        AssemblyName^ asmName = gcnew AssemblyName("PInvokeTest");
        AssemblyBuilder^ dynamicAsm = AppDomain::CurrentDomain->DefineDynamicAssembly(
            asmName, 
            AssemblyBuilderAccess::RunAndSave
        );

        // Create the module.
        ModuleBuilder^ dynamicMod = 
            dynamicAsm->DefineDynamicModule(asmName->Name, asmName->Name + ".dll");

        // Create the TypeBuilder for the class that will contain the 
        // signature for the PInvoke call.
        TypeBuilder^ tb = dynamicMod->DefineType(
            "MyType", 
            TypeAttributes::Public | TypeAttributes::UnicodeClass
        );
    
        MethodBuilder^ mb = tb->DefinePInvokeMethod(
            "GetTickCount",
            "Kernel32.dll",
            MethodAttributes::Public | MethodAttributes::Static | MethodAttributes::PinvokeImpl,
            CallingConventions::Standard,
            int::typeid,
            Type::EmptyTypes,
            CallingConvention::Winapi,
            CharSet::Ansi);

        // Add PreserveSig to the method implementation flags. NOTE: If this line
        // is commented out, the return value will be zero when the method is
        // invoked.
        mb->SetImplementationFlags(
            mb->GetMethodImplementationFlags() | MethodImplAttributes::PreserveSig);

        // The PInvoke method does not have a method body. 

        // Create the class and test the method.
        Type^ t = tb->CreateType();

        MethodInfo^ mi = t->GetMethod("GetTickCount");
        Console::WriteLine("Testing PInvoke method...");
        Console::WriteLine("GetTickCount returned: {0}", mi->Invoke(nullptr, nullptr));

        // Produce the .dll file.
        Console::WriteLine("Saving: " + asmName->Name + ".dll");
        dynamicAsm->Save(asmName->Name + ".dll");
    };

/* This example produces output similar to the following:

Testing PInvoke method...
GetTickCount returned: 1314410994
Saving: PInvokeTest.dll
 */
using System;
using System.Text;
using System.Reflection;
using System.Reflection.Emit;
using System.Runtime.InteropServices;

public class Example
{
    public static void Main()
    {
        // Create the AssemblyBuilder.
        AssemblyName asmName = new AssemblyName("PInvokeTest");
        AssemblyBuilder dynamicAsm = AppDomain.CurrentDomain.DefineDynamicAssembly(
            asmName,
            AssemblyBuilderAccess.RunAndSave
        );

        // Create the module.
        ModuleBuilder dynamicMod =
            dynamicAsm.DefineDynamicModule(asmName.Name, asmName.Name + ".dll");

        // Create the TypeBuilder for the class that will contain the
        // signature for the PInvoke call.
        TypeBuilder tb = dynamicMod.DefineType(
            "MyType",
            TypeAttributes.Public | TypeAttributes.UnicodeClass
        );

        MethodBuilder mb = tb.DefinePInvokeMethod(
            "GetTickCount",
            "Kernel32.dll",
            MethodAttributes.Public | MethodAttributes.Static | MethodAttributes.PinvokeImpl,
            CallingConventions.Standard,
            typeof(int),
            Type.EmptyTypes,
            CallingConvention.Winapi,
            CharSet.Ansi);

        // Add PreserveSig to the method implementation flags. NOTE: If this line
        // is commented out, the return value will be zero when the method is
        // invoked.
        mb.SetImplementationFlags(
            mb.GetMethodImplementationFlags() | MethodImplAttributes.PreserveSig);

        // The PInvoke method does not have a method body.

        // Create the class and test the method.
        Type t = tb.CreateType();

        MethodInfo mi = t.GetMethod("GetTickCount");
        Console.WriteLine("Testing PInvoke method...");
        Console.WriteLine("GetTickCount returned: {0}", mi.Invoke(null, null));

        // Produce the .dll file.
        Console.WriteLine("Saving: " + asmName.Name + ".dll");
        dynamicAsm.Save(asmName.Name + ".dll");
    }
}

/* This example produces output similar to the following:

Testing PInvoke method...
GetTickCount returned: 1312576235
Saving: PInvokeTest.dll
 */
Imports System.Text
Imports System.Reflection
Imports System.Reflection.Emit
Imports System.Runtime.InteropServices

Public Class Example
    
    Public Shared Sub Main() 
        
        ' Create the AssemblyBuilder.
        Dim asmName As New AssemblyName("PInvokeTest")
        Dim dynamicAsm As AssemblyBuilder = _
            AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, _
                AssemblyBuilderAccess.RunAndSave)
        
        ' Create the module.
        Dim dynamicMod As ModuleBuilder = _
            dynamicAsm.DefineDynamicModule(asmName.Name, asmName.Name & ".dll")
        
        ' Create the TypeBuilder for the class that will contain the 
        ' signature for the PInvoke call.
        Dim tb As TypeBuilder = dynamicMod.DefineType("MyType", _
            TypeAttributes.Public Or TypeAttributes.UnicodeClass)
        
        Dim mb As MethodBuilder = tb.DefinePInvokeMethod( _
            "GetTickCount", _
            "Kernel32.dll", _
            MethodAttributes.Public Or MethodAttributes.Static Or MethodAttributes.PinvokeImpl, _
            CallingConventions.Standard, _
            GetType(Integer), _
            Type.EmptyTypes, _
            CallingConvention.Winapi, _
            CharSet.Ansi)

        ' Add PreserveSig to the method implementation flags. NOTE: If this line
        ' is commented out, the return value will be zero when the method is
        ' invoked.
        mb.SetImplementationFlags( _
            mb.GetMethodImplementationFlags() Or MethodImplAttributes.PreserveSig)
        
        ' The PInvoke method does not have a method body.
        
        ' Create the class and test the method.
        Dim t As Type = tb.CreateType()

        Dim mi As MethodInfo = t.GetMethod("GetTickCount")
        Console.WriteLine("Testing PInvoke method...")
        Console.WriteLine("GetTickCount returned: {0}", mi.Invoke(Nothing, Nothing))

        ' Produce the .dll file.
        Console.WriteLine("Saving: " & asmName.Name & ".dll")
        dynamicAsm.Save(asmName.Name & ".dll")
    
    End Sub  
End Class 

' This example produces output similar to the following:
'
'Testing PInvoke method...
'GetTickCount returned: 1313078714
'Saving: PInvokeTest.dll

Hinweise

Einige DLL-Importattribute (siehe Beschreibung von DllImportAttribute) können nicht als Argumente für diese Methode angegeben werden. Beispielsweise muss das DLL-Import-Attribut MethodImplAttributes.PreserveSig hinzugefügt werden, nachdem die PInvoke Methode erstellt wurde, wenn die Methode einen Wert zurückgibt. Das Beispiel zeigt, wie dies geschieht.

Hinweis

Weitere Informationen zu benutzerdefinierten Modifizierern finden Sie unter ECMA C# und Common Language Infrastructure Standards und Standard ECMA-335 – Common Language Infrastructure (CLI).

Gilt für: