如何:使用 C++ 互操作封送 ANSI 字符串
本主题演示如何使用 C++ 互操作传递 ANSI 字符串,但.NET Framework String 表示 Unicode 格式的字符串,因此转换为 ANSI 是一个额外的步骤。 若要与其他字符串类型进行互操作,请参阅以下主题:
以下代码示例使用 managed 和 unmanaged #pragma 指令在同一文件中实现托管和非托管函数,但如果这些函数在单独的文件中定义,则将以相同方式进行交互。 由于仅包含非托管函数的文件不需要使用 /clr(公共语言运行时编译)进行编译,因此它们可以保留其性能特征。
示例:传递 ANSI 字符串
该示例演示如何使用 StringToHGlobalAnsi 将 ANSI 字符串从托管函数传递到非托管函数。 此方法在非托管堆上分配内存,并在执行转换后返回地址。 这意味着不需要固定(因为 GC 堆上的内存不会传递到非托管函数),并且必须显式释放从 StringToHGlobalAnsi 中返回的 IntPtr 或意味着内存泄漏结果。
// 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();
}