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

本主题演示 Visual C++ 互操作性的一个方面。 有关详细信息,请参阅使用 C++ 互操作(隐式 PInvoke)

以下代码示例使用 managed 和 unmanaged #pragma 指令在同一文件中实现托管和非托管函数,但如果这些函数在单独的文件中定义,则将以相同方式进行交互。 仅包含非托管函数的文件不需要使用 /clr(公共语言运行时编译)进行编译。

本主题演示如何将 Unicode 字符串从托管函数传递到非托管函数,或者反向传递。 若要与其他字符串类型进行互操作,请参阅以下主题:

示例:将 Unicode 字符串从托管函数传递到非托管函数

要将 Unicode 字符串从托管函数传递到非托管函数,可以使用 PtrToStringChars 函数(在 Vcclr.h 中声明)来访问存储托管字符串的内存。 由于此地址将传递给本机函数,因此如果在非托管函数执行时发生垃圾回收循环,则使用 pin_ptr (C++/CLI) 固定内存以防止字符串数据被重新定位便非常重要。

// MarshalUnicode1.cpp
// compile with: /clr
#include <iostream>
#include <stdio.h>
#include <vcclr.h>

using namespace std;

using namespace System;
using namespace System::Runtime::InteropServices;

#pragma unmanaged

void NativeTakesAString(const wchar_t* p) {
   printf_s("(native) received '%S'\n", p);
}

#pragma managed

int main() {
   String^ s = gcnew String("test string");
   pin_ptr<const wchar_t> str = PtrToStringChars(s);

   Console::WriteLine("(managed) passing string to native func...");
   NativeTakesAString( str );
}

示例:访问 Unicode 字符串所需的数据封送

以下示例演示了访问由非托管函数调用的托管函数中的 Unicode 字符串所需的数据封送。 托管函数在接收到本机 Unicode 字符串时,使用 PtrToStringUni 方法将其转换为托管字符串。

// MarshalUnicode2.cpp
// compile with: /clr
#include <iostream>

using namespace std;
using namespace System;
using namespace System::Runtime::InteropServices;

#pragma managed

void ManagedStringFunc(wchar_t* s) {
   String^ ms = Marshal::PtrToStringUni((IntPtr)s);
   Console::WriteLine("(managed) received '{0}'", ms);
}

#pragma unmanaged

void NativeProvidesAString() {
   cout << "(unmanaged) calling managed func...\n";
   ManagedStringFunc(L"test string");
}

#pragma managed

int main() {
   NativeProvidesAString();
}

另请参阅

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