Compartilhar via


Funções externas

Este artigo descreve o suporte à linguagem F# para chamar funções no código nativo.

Sintaxe

[<DllImport( arguments )>]
extern declaration

Comentários

Na sintaxe previamente apresentada, arguments representa os argumentos que são fornecidos para o atributo System.Runtime.InteropServices.DllImportAttribute. O primeiro argumento é uma cadeia de caracteres que representa o nome da DLL que contém essa função sem a extensão .dll. Argumentos adicionais podem ser fornecidos para qualquer uma das propriedades públicas da classe System.Runtime.InteropServices.DllImportAttribute, como a convenção de chamada.

Suponha que você tenha uma DLL C++ nativa que contenha a função exportada a seguir.

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

Você pode chamar essa função de F# usando o código a seguir.

open System.Runtime.InteropServices

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

InteropWithNative.HelloWorld()

A interoperabilidade com código nativo é chamada de invocação de plataforma e é um recurso do CLR. Para mais informações, confira Interoperar com código não gerenciado. As informações nessa seção são aplicáveis a F#.

Definição de Parâmetros em Funções Externas

Ao declarar funções externas com valores ou parâmetros retornados, você utiliza uma sintaxe semelhante à do C. Você tem a opção de usar as declarações gerenciadas (em que o CLR realizará algumas conversões automáticas entre tipos nativos e o .NET) e as declarações não gerenciadas, que podem oferecer melhor desempenho em algumas circunstâncias. Por exemplo, a função do Windows GetBinaryTypeW pode ser declarada de duas maneiras 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) instrui o CLR a executar uma conversão automática entre uma representação de cadeia de caracteres nativa do Windows e do .NET string quando a função for chamada. uint& declara um uint que será passado byref, ou seja, como um ponteiro gerenciado. Para obter um ponteiro gerenciado, você deve usar o endereço do operador &.

Alternativamente, você pode desejar gerenciar manualmente o marshalling dos tipos de dados e declarar as funções externas utilizando apenas os tipos não gerenciados.

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

Você pode utilizarMarshal.StringToHGlobalUni para converter uma cadeia de caracteres .NET em formato nativo e receber um ponteiro (nativeint) para ela, que poderá ser fornecido para lpApplicationName.

Para obter um ponteiro para um número inteiro, utilize o ponteiro do operador && ou a palavra-chave fixed.

Confira também