Compartir a través de


Funciones externas

Este artículo describe la compatibilidad del lenguaje F# para llamar a funciones en código nativo.

Sintaxis

[<DllImport( arguments )>]
extern declaration

Comentarios

En la sintaxis anterior, arguments representa los argumentos proporcionados al atributo System.Runtime.InteropServices.DllImportAttribute. 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 clase System.Runtime.InteropServices.DllImportAttribute, 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 utiliza una sintaxis similar a la de C. Existe la opción de utilizar las declaraciones administradas (en las que el CLR realizará algunas conversiones automáticas entre tipos nativos y tipos .NET) y no administradas, que pueden 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 desee 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 palabra clave fixed.

Consulte también