Compartilhar via


Como: realizar realizar marshaling matrizes usando PInvoke

Este tópico explica como nativo funções que aceitam seqüências de caracteres de estilo C podem ser chamadas usando a seqüência de caracteres CLR digite String usando o suporte de invocação de plataforma do .NET estrutura. O Visual C++ programadores são incentivados a usar os recursos de interoperabilidade C++ em vez disso (quando for possível) porque P/Invoke fornece relatórios de erro em time de compilar pouco, não é fortemente tipado e pode ser entediante implementar.Se a API não gerenciada é empacotada sistema autônomo uma DLL e o código-fonte não está disponível, P/Invoke é a única opção (caso contrário, consulte Usando a interoperabilidade de C++ (PInvoke implícita)).

Exemplo

Como matrizes nativo e gerenciados são dispostas diferente na memória, passar-os com êxito por limite gerenciado/requer conversão ou de marshaling.Este tópico demonstra como uma matriz de itens simples (blitable) pode ser passada para nativo funções do código gerenciado.

Assim sistema autônomo dos dados gerenciados/não gerenciados em geral, o marshaling de DllImportAttribute atributo é usado para criar um ponto de entrada gerenciado para cada função nativa que será usado. No caso das funções que utilizam matrizes sistema autônomo argumentos, o MarshalAsAttribute atributo deve ser usado também para especificar para o compilador sistema autônomo sistema autônomo dados irão ser empacotados. No exemplo a seguir, a LPArray enumeração é usada para indicar que o array gerenciado será empacotado sistema autônomo uma matriz de estilo C.

O código a seguir consiste em um não-gerenciados e um módulo gerenciado.O módulo não gerenciado é uma DLL que define uma função que aceita uma matriz de inteiros.O segundo módulo é um aplicativo de linha de comando gerenciado que importa essa função, mas define em termos de uma matriz gerenciada e usa o MarshalAsAttribute atributo para especificar que a matriz deve ser convertida em um array nativo quando chamado.

O módulo gerenciado é compilado com/CLR, mas com/CLR: pura funciona bem.

// TraditionalDll4.cpp
// compile with: /LD /EHsc
#include <iostream>

#define TRADITIONALDLL_EXPORTS
#ifdef TRADITIONALDLL_EXPORTS
#define TRADITIONALDLL_API __declspec(dllexport)
#else
#define TRADITIONALDLL_API __declspec(dllimport)
#endif

extern "C" {
   TRADITIONALDLL_API void TakesAnArray(int len, int[]);
}

void TakesAnArray(int len, int a[]) {
   printf_s("[unmanaged]\n");
   for (int i=0; i<len; i++)
      printf("%d = %d\n", i, a[i]);
}

// MarshalBlitArray.cpp
// compile with: /clr
using namespace System;
using namespace System::Runtime::InteropServices;

value struct TraditionalDLL {
   [DllImport("TraditionalDLL4.dll")]
   static public void TakesAnArray(
   int len,[MarshalAs(UnmanagedType::LPArray)]array<int>^);
};

int main() {
   array<int>^ b = gcnew array<int>(3);
   b[0] = 11;
   b[1] = 33;
   b[2] = 55;
   TraditionalDLL::TakesAnArray(3, b);

   Console::WriteLine("[managed]");
   for (int i=0; i<3; i++)
      Console::WriteLine("{0} = {1}", i, b[i]);
}

Observe que nenhuma parte da DLL seja exposto no código gerenciado através de # tradicional diretiva include.Na verdade, porque a DLL é acessada no time de execução somente, problemas com funções importados com DllImportAttribute não serão detectados no momento da compilar.

Consulte também

Outros recursos

Usar PInvoke Explicit no C++ (atributo DllImport)