Практическое руководство. Маршалирование строк ANSI с использованием взаимодействия C++
В этом разделе показано, как можно передавать строки ANSI с помощью взаимодействия C++, но платформа .NET Framework String представляет строки в формате Юникода, поэтому преобразование в ANSI является дополнительным шагом. Сведения о взаимодействии с другими типами строк см. в следующих разделах:
Практическое руководство. Маршалинг строк Юникода с использованием взаимодействия C++
Практическое руководство. Маршалинг строк COM с помощью взаимодействия C++
В следующих примерах кода используются управляемые неуправляемые директивы #pragma для реализации управляемых и неуправляемых функций в одном файле, но эти функции взаимодействуют одинаково, если они определены в отдельных файлах. Так как файлы, содержащие только неуправляемые функции, не нужно компилировать с помощью /clr (компиляция среды clr) они могут сохранять свои характеристики производительности.
Пример. Передача строки ANSI
В примере демонстрируется передача строки ANSI из управляемой в неуправляемую функцию с помощью StringToHGlobalAnsi. Этот метод выделяет память на неуправляемой куче и возвращает адрес после выполнения преобразования. Это означает, что не требуется закрепление (так как память в куче GC не передается в неуправляемую функцию) и что intPtr, возвращенный из StringToHGlobalAnsi него, должен быть явно освобожден или результаты утечки памяти.
// MarshalANSI1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma unmanaged
void NativeTakesAString(const char* p) {
printf_s("(native) received '%s'\n", p);
}
#pragma managed
int main() {
String^ s = gcnew String("sample string");
IntPtr ip = Marshal::StringToHGlobalAnsi(s);
const char* str = static_cast<const char*>(ip.ToPointer());
Console::WriteLine("(managed) passing string...");
NativeTakesAString( str );
Marshal::FreeHGlobal( ip );
}
Пример. Маршалинг данных, необходимый для доступа к строке ANSI
В следующем примере демонстрируется маршалинг данных, необходимый для доступа к строке ANSI в управляемой функции, вызываемой неуправляемой функцией. Управляемая функция, получающая собственную строку, может использовать ее напрямую или преобразовать ее в управляемую строку с помощью PtrToStringAnsi метода, как показано ниже.
// MarshalANSI2.cpp
// compile with: /clr
#include <iostream>
#include <vcclr.h>
using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;
#pragma managed
void ManagedStringFunc(char* s) {
String^ ms = Marshal::PtrToStringAnsi(static_cast<IntPtr>(s));
Console::WriteLine("(managed): received '{0}'", ms);
}
#pragma unmanaged
void NativeProvidesAString() {
cout << "(native) calling managed func...\n";
ManagedStringFunc("test string");
}
#pragma managed
int main() {
NativeProvidesAString();
}