TypeBuilder.DefinePInvokeMethod 方法

定义

定义 PInvoke 方法。

重载

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

定义 PInvoke 方法,指定方法的名称、定义方法所使用的 DLL 的名称、方法的属性、方法的调用约定、 方法的返回类型、 方法的参数类型,以及 PInvoke 标志。

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

定义 PInvoke 方法,指定方法的名称、定义方法所使用的 DLL 的名称、入口点名称、 方法的属性、方法的调用约定、 方法的返回类型、 方法的参数类型,以及 PInvoke 标志。

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

定义 PInvoke 方法,指定方法的名称、定义方法所使用的 DLL 的名称、入口点名称、方法的属性、方法的调用约定、方法的返回类型、方法的参数类型、PInvoke 标志,以及参数和返回类型的自定义修饰符。

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

Source:
TypeBuilder.cs
Source:
TypeBuilder.cs
Source:
TypeBuilder.cs

定义 PInvoke 方法,指定方法的名称、定义方法所使用的 DLL 的名称、方法的属性、方法的调用约定、 方法的返回类型、 方法的参数类型,以及 PInvoke 标志。

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

参数

name
String

PInvoke 方法的名称。 name 不能包含嵌入的 null。

dllName
String

定义 PInvoke 方法所使用的 DLL 的名称。

attributes
MethodAttributes

方法的属性。

callingConvention
CallingConventions

方法的调用约定。

returnType
Type

方法的返回类型。

parameterTypes
Type[]

方法参数的类型。

nativeCallConv
CallingConvention

本地调用约定。

nativeCharSet
CharSet

方法的本地字符集。

返回

已定义的 PInvoke 方法。

例外

此方法不是静态的。

- 或 -

此父类型为一个接口。

- 或 -

这种方法是抽象的方法。

- 或 -

此方法之前已定义。

- 或 -

namedllName 的长度为零。

namedllNamenull

之前已使用 CreateType() 创建包含类型。

示例

下面的示例演示如何使用 DefinePInvokeMethod 方法创建 PInvoke 方法,以及如何使用 和 MethodBuilder.SetImplementationFlags 方法创建 MethodBuilder.GetMethodImplementationFlagsMethodBuilder后将标志添加到MethodImplAttributes.PreserveSig方法实现标志。

重要

若要获取非零返回值,必须添加 MethodImplAttributes.PreserveSig 标志。

该示例创建一个动态程序集,其中包含一个动态模块和一个包含 PInvoke 方法的单个类型 MyType。 方法 PInvoke 表示 Win32 GetTickCount 函数。

运行示例时,它将执行 PInvoke 方法。 它还将动态程序集保存为 PInvokeTest.dll。 可以使用 Ildasm.exe (IL 反汇编程序) 检查 MyType 类及其 static 包含) Shared 方法的 Visual Basic 中的 (PInvoke 。 在运行 csc.exe 或 vbc.exe 时,可以通过包含对 DLL 的引用来编译使用静态MyType.GetTickCount方法的 Visual Basic 或 C# 程序;例如 。 /r:PInvokeTest.dll

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

注解

某些 DLL 导入属性 (查看) 的说明 DllImportAttribute 无法指定为此方法的参数。 例如,如果方法返回值,则必须在创建方法后PInvoke添加 DLL 导入属性MethodImplAttributes.PreserveSig。 该示例演示如何执行此操作。

适用于

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

Source:
TypeBuilder.cs
Source:
TypeBuilder.cs
Source:
TypeBuilder.cs

定义 PInvoke 方法,指定方法的名称、定义方法所使用的 DLL 的名称、入口点名称、 方法的属性、方法的调用约定、 方法的返回类型、 方法的参数类型,以及 PInvoke 标志。

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

参数

name
String

PInvoke 方法的名称。 name 不能包含嵌入的 null。

dllName
String

定义 PInvoke 方法所使用的 DLL 的名称。

entryName
String

DLL 中入口点的名称。

attributes
MethodAttributes

方法的属性。

callingConvention
CallingConventions

方法的调用约定。

returnType
Type

方法的返回类型。

parameterTypes
Type[]

方法参数的类型。

nativeCallConv
CallingConvention

本地调用约定。

nativeCharSet
CharSet

方法的本地字符集。

返回

已定义的 PInvoke 方法。

例外

此方法不是静态的。

- 或 -

此父类型为一个接口。

- 或 -

这种方法是抽象的方法。

- 或 -

此方法之前已定义。

- 或 -

namedllNameentryName 的长度为零。

namedllNameentryNamenull

之前已使用 CreateType() 创建包含类型。

示例

下面的代码示例演示如何使用 DefinePInvokeMethod 方法创建 PInvoke 方法,以及如何在创建 MethodBuilder后使用 MethodBuilder.GetMethodImplementationFlagsMethodBuilder.SetImplementationFlags 方法将标志添加到MethodImplAttributes.PreserveSig方法实现标志。

重要

若要获取非零返回值,必须添加 MethodImplAttributes.PreserveSig 标志。

该示例创建一个动态程序集,其中包含一个动态模块和一个包含 PInvoke 方法的单个类型 MyType。 方法 PInvoke 表示 Win32 GetTickCount 函数。

运行示例时,它将执行 PInvoke 方法。 它还将动态程序集保存为 PInvokeTest.dll。 可以使用 Ildasm.exe (IL 反汇编程序) 检查 MyType 类及其 static 包含) Shared 方法的 Visual Basic 中的 (PInvoke 。 在运行 csc.exe 或 vbc.exe 时,可以通过包含对 DLL 的引用来编译使用静态MyType.GetTickCount方法的 Visual Basic 或 C# 程序;例如 。 /r:PInvokeTest.dll

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

注解

某些 DLL 导入属性 (查看) 的说明 DllImportAttribute 无法指定为此方法的参数。 例如,如果方法返回值,则必须在创建方法后PInvoke添加 DLL 导入属性MethodImplAttributes.PreserveSig。 该示例演示如何执行此操作。

适用于

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

Source:
TypeBuilder.cs
Source:
TypeBuilder.cs
Source:
TypeBuilder.cs

定义 PInvoke 方法,指定方法的名称、定义方法所使用的 DLL 的名称、入口点名称、方法的属性、方法的调用约定、方法的返回类型、方法的参数类型、PInvoke 标志,以及参数和返回类型的自定义修饰符。

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

参数

name
String

PInvoke 方法的名称。 name 不能包含嵌入的 null。

dllName
String

定义 PInvoke 方法所使用的 DLL 的名称。

entryName
String

DLL 中入口点的名称。

attributes
MethodAttributes

方法的属性。

callingConvention
CallingConventions

方法的调用约定。

returnType
Type

方法的返回类型。

returnTypeRequiredCustomModifiers
Type[]

一个类型数组,表示该方法的返回类型所必需的自定义修饰符,如 IsConst。 如果返回类型没有所需的自定义修饰符,则指定 null

returnTypeOptionalCustomModifiers
Type[]

一个类型数组,表示该方法的返回类型的可选自定义修饰符,如 IsConst。 如果返回类型没有可选的自定义修饰符,则指定 null

parameterTypes
Type[]

方法参数的类型。

parameterTypeRequiredCustomModifiers
Type[][]

由类型数组组成的数组。 每个类型数组均表示相应参数所必需的自定义修饰符,如 IsConst。 如果某个特定参数没有所需的自定义修饰符,则指定 null,而不要指定类型数组。 如果所有参数都没有所需的自定义修饰符,则指定 null,而不要指定由数组组成的数组。

parameterTypeOptionalCustomModifiers
Type[][]

由类型数组组成的数组。 每个类型数组均表示相应参数的可选自定义修饰符,如 IsConst。 如果某个特定参数没有可选的自定义修饰符,则指定 null,而不要指定类型数组。 如果所有参数都没有可选的自定义修饰符,则指定 null,而不要指定由数组组成的数组。

nativeCallConv
CallingConvention

本地调用约定。

nativeCharSet
CharSet

方法的本地字符集。

返回

一个 MethodBuilder,表示所定义的 PInvoke 方法。

例外

此方法不是静态的。

- 或 -

此父类型为一个接口。

- 或 -

这种方法是抽象的方法。

- 或 -

此方法之前已定义。

- 或 -

namedllNameentryName 的长度为零。

- 或 -

parameterTypeRequiredCustomModifiersparameterTypeOptionalCustomModifiers 的大小与 parameterTypes 的大小不相等。

namedllNameentryNamenull

该类型是以前使用 CreateType() 创建的。

- 或 -

对于当前的动态类型,属性 IsGenericType 的值为 true,但属性 IsGenericTypeDefinition 的值为 false

示例

下面的代码示例演示如何使用 DefinePInvokeMethod 方法创建 PInvoke 方法,以及如何在创建 MethodBuilder后使用 MethodBuilder.GetMethodImplementationFlagsMethodBuilder.SetImplementationFlags 方法将标志添加到MethodImplAttributes.PreserveSig方法实现标志。

该示例创建一个动态程序集,其中包含一个动态模块和一个包含 PInvoke 方法的单个类型 MyType。 方法 PInvoke 表示 Win32 GetTickCount 函数。

重要

若要获取非零返回值,必须添加 MethodImplAttributes.PreserveSig 标志。

注意

该示例使用不指定自定义修饰符的重载。 若要指定自定义修饰符,请将示例代码更改为改用此方法重载。

运行示例时,它将执行 PInvoke 方法。 它还将动态程序集保存为 PInvokeTest.dll。 可以使用 Ildasm.exe (IL 反汇编程序) 检查 MyType 类及其 static 包含) Shared 方法的 Visual Basic 中的 (PInvoke 。 在运行 csc.exe 或 vbc.exe 时,可以通过包含对 DLL 的引用来编译使用静态MyType.GetTickCount方法的 Visual Basic 或 C# 程序;例如 。 /r:PInvokeTest.dll

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

注解

某些 DLL 导入属性 (查看) 的说明 DllImportAttribute 无法指定为此方法的参数。 例如,如果方法返回值,则必须在创建方法后PInvoke添加 DLL 导入属性MethodImplAttributes.PreserveSig。 该示例演示如何执行此操作。

注意

有关自定义修饰符的详细信息,请参阅 ECMA C# 和公共语言基础结构标准 以及 标准 ECMA-335 - 公共语言基础结构 (CLI)

适用于