Share via


Como: realizar realizar marshaling strings 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 sistema::String utilizando suporte a 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, mas caso contrário, consulte Usando a interoperabilidade de C++ (PInvoke implícita).

Seqüências de caracteres gerenciadas e não gerenciadas são dispostas diferente na memória, para que passar cadeias de caracteres de funções gerenciadas para não gerenciado exige o MarshalAsAttribute atributo para instruir o compilador para inserir os mecanismos de conversão necessária para marshaling de dados de seqüência de caracteres corretamente e com segurança.

sistema autônomo ocorre com funções que usam apenas intrínseca tipos de dados, DllImportAttribute usado para declarar sistema autônomo pontos de entrada gerenciado para o nativo funções, mas--para passanado seqüências--em vez de definir esses entrada pontos sistema autônomo tirar seqüências de caracteres de estilo C, um identificador para o String tipo pode ser usado em vez disso. Isso solicita que o compilador a inserir o código que executa a conversão necessária.Para cada argumento de função em uma função não gerenciado que leva uma seqüência de caracteres, a MarshalAsAttribute atributo deve ser usado para indicar que o objeto String deve ser empacotado para o nativo funcionar sistema autônomo uma seqüência de caracteres de estilo C.

Exemplo

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 chamada TakesAString que aceita uma cadeia de caracteres ANSI do estilo C na forma de um char *.O módulo gerenciado é um aplicativo de linha de comando que importa a função TakesAString, mas define sistema autônomo tirar um sistema.String gerenciado em vez de um char *.The MarshalAsAttribute atributo é usado para indicar como o gerenciado seqüência de caracteres deve ser empacotada quando TakesAString é chamado.

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

// TraditionalDll2.cpp
// compile with: /LD /EHsc
#include <windows.h>
#include <stdio.h>
#include <iostream>

using namespace std;

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

extern "C" {
   TRADITIONALDLL_API void TakesAString(char*);
}

void TakesAString(char* p) {
   printf_s("[unmanaged] %s\n", p);
}

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

value struct TraditionalDLL
{
   [DllImport("TraditionalDLL2.dll")]
      static public void 
      TakesAString([MarshalAs(UnmanagedType::LPStr)]String^);
};

int main() {
   String^ s = gcnew String("sample string");
    Console::WriteLine("[managed] passing managed string to unmanaged function...");
   TraditionalDLL::TakesAString(s);
   Console::WriteLine("[managed] {0}", s);
}

Essa técnica faz com que uma cópia de seqüência de caracteres para ser construído no heap não gerenciada, para que as alterações efetuadas na seqüência de caracteres, a função nativa não serão refletidas na cópia gerenciada da seqüência de caracteres.

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

Consulte também

Outros recursos

Usar PInvoke Explicit no C++ (atributo DllImport)