Поделиться через


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

Определяет метод 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

Имя библиотеки 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 .

Важно!

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

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

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

Комментарии

Некоторые атрибуты импорта DllImportAttributeDLL (см. описание ) не могут быть указаны в качестве аргументов этого метода. Например, атрибут MethodImplAttributes.PreserveSig импорта DLL должен быть добавлен после PInvoke создания метода, если метод возвращает значение. В примере показано, как это сделать.

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

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

Исходный код:
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);
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

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

entryName
String

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

attributes
MethodAttributes

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

callingConvention
CallingConventions

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

returnType
Type

Возвращаемый тип метода.

parameterTypes
Type[]

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

nativeCallConv
CallingConvention

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

nativeCharSet
CharSet

Собственная кодировка метода.

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

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

Исключения

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

-или-

Родительский тип является интерфейсом.

-или-

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

-или-

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

-или-

Длина параметра name, dllName или entryName равна нулю.

Значение параметра name, dllName или entryName равно null.

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

Примеры

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

Важно!

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

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

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

Комментарии

Некоторые атрибуты импорта DllImportAttributeDLL (см. описание ) не могут быть указаны в качестве аргументов этого метода. Например, атрибут MethodImplAttributes.PreserveSig импорта DLL должен быть добавлен после PInvoke создания метода, если метод возвращает значение. В примере показано, как это сделать.

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

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

Исходный код:
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);
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

Имя библиотеки 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, dllName или entryName равно null.

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

-или-

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

Примеры

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

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

Важно!

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

Примечание

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

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

Комментарии

Некоторые атрибуты импорта DllImportAttributeDLL (см. описание ) нельзя указать в качестве аргументов для этого метода. Например, атрибут MethodImplAttributes.PreserveSig импорта DLL должен быть добавлен после PInvoke создания метода, если метод возвращает значение. В примере показано, как это сделать.

Примечание

Дополнительные сведения о настраиваемых модификаторах см. в разделах EcMA C# и Common Language Infrastructure Standards and Standard ECMA-335 — COMMON Language Infrastructure (CLI).

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