¿Le resultó útil esta página?
Sus comentarios sobre este contenido son muy importantes. Háganos saber su opinión.
¿Tiene comentarios adicionales?
Caracteres restantes: 1500
Crear prototipos en código administrado
Este artículo se tradujo de forma manual. Mueva el puntero sobre las frases del artículo para ver el texto original. Más información.
Traducción
Original

Crear prototipos en código administrado

En este tema se describe cómo acceder a funciones no administradas y presenta varios campos de atributo que anotan la definición de método en el código administrado. Para obtener ejemplos que muestran cómo construir declaraciones basadas en .NET para usarse con la invocación de plataforma, consulte Calcular las referencias de datos con invocación de plataforma.

Antes de poder acceder a una función DLL no administrada desde código administrado, deberá conocer el nombre de la función y el nombre del archivo DLL que la exporta. Con esta información, puede empezar a escribir la definición administrada de una función no administrada que se implementa en un archivo DLL. Además, puede ajustar la manera en que la invocación de plataforma crea la función y calcula las referencias de los datos desde y hacia la función.

Nota Nota

Las funciones de la API Win32 que asignan una cadena permiten liberar la cadena usando un método como LocalFree. La invocación de plataforma controla estos parámetros de forma diferente. Para las llamadas de invocación de plataforma, haga que el parámetro sea del tipo IntPtr en lugar del tipo String. Use los métodos que proporciona la clase System.Runtime.InteropServices.Marshal para convertir el tipo a una cadena manualmente y liberarla manualmente.

Las definiciones administradas de funciones no administradas dependen del lenguaje, como puede ver en los ejemplos siguientes. Para obtener ejemplos de código más completos, consulte Ejemplos de invocación de plataforma.

Imports System.Runtime.InteropServices
Public Class Win32
    Declare Auto Function MessageBox Lib "user32.dll" _
       (ByVal hWnd As Integer, _
        ByVal txt As String, ByVal caption As String, _
        ByVal Typ As Integer) As IntPtr
End Class

Para aplicar los campos BestFitMapping, CallingConvention, ExactSpelling, PreserveSig, SetLastError o ThrowOnUnmappableChar a una declaración Microsoft Visual Basic 2005, debe usar el atributo DllImportAttribute en lugar de la instrucción Declare.

using System.Runtime.InteropServices;
[DllImport("user32.dll")]
    public static extern IntPtr MessageBox(int hWnd, String text, 
                                       String caption, uint type);

Tanto si se establece explícitamente como si no, los campos de atributo definen el comportamiento del código administrado. La invocación de plataforma funciona según los valores predeterminados establecidos en diversos campos que existen como metadatos en un ensamblado. Puede modificar este comportamiento predeterminado ajustando los valores de uno o más campos. En muchos casos, se usa DllImportAttribute para establecer un valor.

En la tabla siguiente se muestra el conjunto completo de campos de atributo que pertenecen a la invocación de plataforma. Para cada campo, la tabla incluye el valor predeterminado y un vínculo a información sobre cómo usar estos campos para definir funciones DLL no administradas.

Campo

Descripción

[ F:System.Runtime.InteropServices.DllImportAttribute.BestFitMapping ]

Habilita o deshabilita la asignación con ajuste perfecto.

[ F:System.Runtime.InteropServices.DllImportAttribute.CallingConvention ]

Especifica la convención de llamada que se usará al pasar argumentos de método. El valor predeterminado es WinAPI, que corresponde a __stdcall para las plataformas de 32 bits basadas en Intel.

[ F:System.Runtime.InteropServices.DllImportAttribute.CharSet ]

Controla la eliminación de nombres y la forma en que deben calcularse las referencias de los argumentos de cadena a la función. De manera predeterminada, es CharSet.Ansi.

[ F:System.Runtime.InteropServices.DllImportAttribute.EntryPoint ]

Especifica el punto de entrada DLL al que se debe llamar.

[ F:System.Runtime.InteropServices.DllImportAttribute.ExactSpelling ]

Controla si un punto de entrada debe modificarse para que coincida con el juego de caracteres. El valor predeterminado varía según el lenguaje de programación.

[ F:System.Runtime.InteropServices.DllImportAttribute.PreserveSig ]

Controla si la firma del método administrado debería transformarse en una firma no administrada que devuelve un resultado HRESULT y tiene un argumento adicional [out, retval] para el valor devuelto.

El valor predeterminado es true (la firma no debe transformarse).

[ F:System.Runtime.InteropServices.DllImportAttribute.SetLastError ]

Permite al llamador usar la función Marshal.GetLastWin32Error de la API para determinar si se produjo un error al ejecutar el método. En Visual Basic, el valor predeterminado es true; en C# y C++, el valor predeterminado es false.

[ F:System.Runtime.InteropServices.DllImportAttribute.ThrowOnUnmappableChar ]

Controla el inicio de una excepción cuando un carácter Unicode que no se puede asignar se convierte en un carácter ANSI "?".

Para obtener información de referencia detallada, consulte DllImportAttribute (Clase).

Los miembros Assert, Deny y PermitOnly de la enumeración SecurityAction se conocen como modificadores del recorrido de la pila. Estos miembros se omiten si se usan como atributos declarativos en declaraciones de invocación de plataforma e instrucciones del lenguaje de definición de interfaz (IDL) COM.

w4byd5y4.collapse_all(es-es,VS.110).gifEjemplos de invocación de plataforma

Los ejemplos de invocación de plataforma de esta sección muestran el uso del atributo RegistryPermission con los modificadores del recorrido de la pila.

En el ejemplo de código siguiente, se omiten los modificadores SecurityActionAssert, Deny y PermitOnly.

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
    private static extern bool CallRegistryPermissionAssert();

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.Deny, Unrestricted = true)]
    private static extern bool CallRegistryPermissionDeny();

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.PermitOnly, Unrestricted = true)]
    private static extern bool CallRegistryPermissionDeny();

Sin embargo, el modificador Demand se acepta en el siguiente ejemplo.

[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
[RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
    private static extern bool CallRegistryPermissionDeny();

Los modificadores SecurityAction funcionan correctamente si se colocan en una clase que contiene (encapsula) la llamada de invocación de plataforma.

[RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
class PInvokeWrapper
{
[DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
    private static extern bool CallRegistryPermissionDeny();
}

Los modificadores SecurityAction también funcionan correctamente en un escenario anidado en el que se colocan en el llamador de la llamada de invocación de plataforma:

class PInvokeScenario
{
    [DllImport("MyClass.dll", EntryPoint = "CallRegistryPermission")]
    private static extern bool CallRegistryPermissionInternal();

    [RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
    public static bool CallRegistryPermission()
    {
     return CallRegistryPermissionInternal();
    }
}

w4byd5y4.collapse_all(es-es,VS.110).gifEjemplos de interoperabilidad COM

Los ejemplos de interoperabilidad COM de esta sección muestran el uso del atributo RegistryPermission con los modificadores del recorrido de la pila.

Las siguientes declaraciones de interfaz de interoperabilidad COM omiten los modificadores Assert, Deny y PermitOnly, de forma similar a los ejemplos de invocación de plataforma de la sección anterior.

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IAssertStubsItf
{
[RegistryPermission(SecurityAction.Assert, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.Assert, Unrestricted = true)]
    bool CallFileIoPermission();
}

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IDenyStubsItf
{
[RegistryPermission(SecurityAction.Deny, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.Deny, Unrestricted = true)]
    bool CallFileIoPermission();
}

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IAssertStubsItf
{
[RegistryPermission(SecurityAction.PermitOnly, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.PermitOnly, Unrestricted = true)]
    bool CallFileIoPermission();
}

Además, el modificador Demand no se acepta en escenarios de declaración de interfaz de interoperabilidad COM, tal y como se muestra en el ejemplo siguiente.

[ComImport, Guid("12345678-43E6-43c9-9A13-47F40B338DE0")]
interface IDemandStubsItf
{
[RegistryPermission(SecurityAction.Demand, Unrestricted = true)]
    bool CallRegistryPermission();
[FileIOPermission(SecurityAction.Demand, Unrestricted = true)]
    bool CallFileIoPermission();
}
Mostrar:
© 2015 Microsoft