如何:使用 C++ 互操作封送 ANSI 字符串

本主题演示如何使用 C++ Interop 传递 ANSI 字符串,但是 .NET Framework String 采用 Unicode 格式表示字符串,因此转换为 ANSI 是一个附加步骤。 要实现与其他字符串类型的交互操作,请参见下列主题:

下面的代码示例使用 managed、unmanaged #pragma 指令在同一个文件中实现托管函数和非托管函数,但如果在不同的文件中定义这些函数,则它们将以同样的方式进行交互操作。 由于不需要使用 /clr(公共语言运行时编译) 编译仅包含非托管函数的文件,因此这些文件可以保留它们的性能特性。

示例

该示例演示如何使用 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 字符串所需的数据封送处理。 托管函数在接收到本机字符串时,可以直接使用该字符串,也可以按所示方式使用 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();
}

请参见

参考

使用 C++ 互操作(隐式 PInvoke)