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)

Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
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);
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")]
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);
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);
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")>]
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
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

Имя библиотеки DLL, в которой PInvoke определен метод.

attributes
MethodAttributes

Атрибуты метода.

callingConvention
CallingConventions

Соглашение о вызовах метода.

returnType
Type

Тип возвращаемого метода.

parameterTypes
Type[]

Типы параметров метода.

nativeCallConv
CallingConvention

Собственное соглашение о вызовах.

nativeCharSet
CharSet

Собственный набор символов метода.

Возвращаемое значение

Определенный PInvoke метод.

Атрибуты

Исключения

Метод не является статическим.

–или–

Родительский тип — это интерфейс.

–или–

Метод является абстрактным.

–или–

Ранее был определен метод.

–или–

Длина name или dllName равна нулю.

name или dllName есть null.

Ранее был создан CreateType()содержащий тип.

Примеры

В следующем примере показано, как использовать DefinePInvokeMethod метод для создания PInvoke метода и как добавить MethodImplAttributes.PreserveSig флаг в флаги реализации метода после создания MethodBuilderметода с помощью MethodBuilder.GetMethodImplementationFlags методов и MethodBuilder.SetImplementationFlags методов.

Important

Чтобы получить ненулевое возвращаемое значение, необходимо добавить MethodImplAttributes.PreserveSig флаг.

В примере создается динамическая сборка с одним динамическим модулем и одним типом, MyTypeсодержащим PInvoke метод. Метод PInvoke представляет функцию Win32 GetTickCount .

При запуске примера выполняется PInvoke метод. Она также сохраняет динамическую сборку как PInvokeTest.dll. Вы можете использовать Ildasm.exe (IL Disassembler) для изучения класса MyType и метода static (Shared в Visual Basic) PInvoke. Можно скомпилировать программу Visual Basic или C#, которая использует статический метод MyType.GetTickCount, включив ссылку на библиотеку DLL при запуске csc.exe или vbc.exe; например, /r: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) нельзя указать в качестве аргументов для этого метода. Например, атрибут MethodImplAttributes.PreserveSig импорта DLL должен быть добавлен после PInvoke создания метода, если метод возвращает значение. В примере показано, как это сделать.

Применяется к

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

Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
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);
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")]
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);
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);
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")>]
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
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

Имя библиотеки DLL, в которой PInvoke определен метод.

entryName
String

Имя точки входа в библиотеке DLL.

attributes
MethodAttributes

Атрибуты метода.

callingConvention
CallingConventions

Соглашение о вызовах метода.

returnType
Type

Тип возвращаемого метода.

parameterTypes
Type[]

Типы параметров метода.

nativeCallConv
CallingConvention

Собственное соглашение о вызовах.

nativeCharSet
CharSet

Собственный набор символов метода.

Возвращаемое значение

Определенный PInvoke метод.

Атрибуты

Исключения

Метод не является статическим.

–или–

Родительский тип — это интерфейс.

–или–

Метод является абстрактным.

–или–

Ранее был определен метод.

–или–

Длина name, dllNameили entryName равно нулю.

name, или dllNameentryName есть null.

Ранее был создан CreateType()содержащий тип.

Примеры

В следующем примере кода показано, как использовать DefinePInvokeMethod метод для создания PInvoke метода и как добавить MethodImplAttributes.PreserveSig флаг в флаги реализации метода после создания MethodBuilderметода с помощью MethodBuilder.GetMethodImplementationFlags методов и MethodBuilder.SetImplementationFlags методов.

Important

Чтобы получить ненулевое возвращаемое значение, необходимо добавить MethodImplAttributes.PreserveSig флаг.

В примере создается динамическая сборка с одним динамическим модулем и одним типом, MyTypeсодержащим PInvoke метод. Метод PInvoke представляет функцию Win32 GetTickCount .

При запуске примера выполняется PInvoke метод. Она также сохраняет динамическую сборку как PInvokeTest.dll. Вы можете использовать Ildasm.exe (IL Disassembler) для изучения класса MyType и метода static (Shared в Visual Basic) PInvoke. Можно скомпилировать программу Visual Basic или C#, которая использует статический метод MyType.GetTickCount, включив ссылку на библиотеку DLL при запуске csc.exe или vbc.exe; например, /r: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) нельзя указать в качестве аргументов для этого метода. Например, атрибут MethodImplAttributes.PreserveSig импорта DLL должен быть добавлен после PInvoke создания метода, если метод возвращает значение. В примере показано, как это сделать.

Применяется к

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

Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
TypeBuilder.cs
Исходный код:
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);
[System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")]
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);
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);
[<System.Diagnostics.CodeAnalysis.RequiresUnreferencedCode("P/Invoke marshalling may dynamically access members that could be trimmed.")>]
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
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

Имя библиотеки DLL, в которой PInvoke определен метод.

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 метод.

Атрибуты

Исключения

Метод не является статическим.

–или–

Родительский тип — это интерфейс.

–или–

Метод является абстрактным.

–или–

Ранее был определен метод.

–или–

Длина name, dllNameили entryName равно нулю.

–или–

Размер parameterTypeRequiredCustomModifiers или parameterTypeOptionalCustomModifiers не равен размеру parameterTypes.

name, или dllNameentryName есть null.

Тип был создан ранее с помощью CreateType().

–или–

Для текущего динамического типа свойство равноIsGenericType, true но IsGenericTypeDefinition свойство равноfalse.

Примеры

В следующем примере кода показано, как использовать DefinePInvokeMethod метод для создания PInvoke метода и как добавить MethodImplAttributes.PreserveSig флаг в флаги реализации метода после создания MethodBuilderметода с помощью MethodBuilder.GetMethodImplementationFlags методов и MethodBuilder.SetImplementationFlags методов.

В примере создается динамическая сборка с одним динамическим модулем и одним типом, MyTypeсодержащим PInvoke метод. Метод PInvoke представляет функцию Win32 GetTickCount .

Important

Чтобы получить ненулевое возвращаемое значение, необходимо добавить MethodImplAttributes.PreserveSig флаг.

Note

В примере используется перегрузка, которая не указывает пользовательские модификаторы. Чтобы указать настраиваемые модификаторы, измените пример кода, чтобы использовать эту перегрузку метода.

При запуске примера выполняется PInvoke метод. Она также сохраняет динамическую сборку как PInvokeTest.dll. Вы можете использовать Ildasm.exe (IL Disassembler) для изучения класса MyType и метода static (Shared в Visual Basic) PInvoke. Можно скомпилировать программу Visual Basic или C#, которая использует статический метод MyType.GetTickCount, включив ссылку на библиотеку DLL при запуске csc.exe или vbc.exe; например, /r: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) нельзя указать в качестве аргументов для этого метода. Например, атрибут MethodImplAttributes.PreserveSig импорта DLL должен быть добавлен после PInvoke создания метода, если метод возвращает значение. В примере показано, как это сделать.

Note

Дополнительные сведения о пользовательских модификаторах см. в статьях ECMA C# и стандартных стандартах инфраструктуры clma-335 — инфраструктуре общего языка (CLI).

Применяется к