Compartir vía


Funciones externas

En este artículo se describe la compatibilidad con lenguaje F# para llamar a funciones en código nativo.

Sintaxis

[<DllImport( arguments )>]
extern declaration

Observaciones

En la sintaxis anterior, arguments representa los argumentos proporcionados al System.Runtime.InteropServices.DllImportAttribute atributo . El primer argumento es una cadena que representa el nombre del archivo DLL que contiene esta función, sin la extensión .dll. Se pueden proporcionar argumentos adicionales para cualquiera de las propiedades públicas de la System.Runtime.InteropServices.DllImportAttribute clase, como la convención de llamada.

Supongamos que tiene un archivo DLL de C++ nativo que contiene la siguiente función exportada.

#include <stdio.h>
extern "C" void __declspec(dllexport) HelloWorld()
{
    printf("Hello world, invoked by F#!\n");
}

Puede llamar a esta función desde F# mediante el código siguiente.

open System.Runtime.InteropServices

module InteropWithNative =
    [<DllImport(@"C:\bin\nativedll", CallingConvention = CallingConvention.Cdecl)>]
    extern void HelloWorld()

InteropWithNative.HelloWorld()

La interoperabilidad con código nativo se conoce como invocación de plataforma y es una característica de CLR. Para más información, consulte Interoperating with Unmanaged Code (Interoperar con código no administrado) La información de esa sección es aplicable a F#.

Definición de parámetros en funciones externas

Al declarar funciones externas con valores devueltos o parámetros, se usa una sintaxis similar a C. Tiene la opción de usar las declaraciones administradas (donde CLR realizará algunas conversiones automáticas entre tipos nativos y .NET) y declaraciones no administradas, lo que podría ofrecer un mejor rendimiento en algunas circunstancias. Por ejemplo, la función de Windows GetBinaryTypeW se puede declarar de dos maneras diferentes:

// Using automatic marshaling of managed types
[<DllImport("kernel32.dll",
    CallingConvention = CallingConvention.StdCall,
    CharSet = CharSet.Unicode,
    ExactSpelling = true)>]
extern bool GetBinaryTypeW([<MarshalAs(UnmanagedType.LPWStr)>] string lpApplicationName, uint& lpBinaryType);

MarshalAs(UnmanagedType.LPWStr) indica al CLR que realice una conversión automática entre una representación de cadena nativa de .NET string y Windows cuando se llama a la función. uint& declara que uint se pasará byref, es decir, como puntero administrado. Para obtener un puntero administrado, use la dirección del & operador .

Como alternativa, es posible que quiera administrar manualmente la serialización de tipos de datos y declarar las funciones externas con solo tipos no administrados.

// Using unmanaged types
[<DllImport("kernel32.dll", CallingConvention = CallingConvention.StdCall, ExactSpelling = true)>]
extern int GetBinaryTypeW(nativeint lpApplicationName, uint* lpBinaryType);

Puede usarMarshal.StringToHGlobalUni para convertir una cadena de .NET en formato nativo y recibir un puntero (nativeint) a ella que se podría proporcionar a lpApplicationName.

Para obtener un puntero a un entero, use el puntero del && operador o la fixed palabra clave .

Consulte también