方法: C++ Interop を使用して Unicode 文字列をマーシャリングする
このトピックでは、Visual C++ の相互運用性の 1 つのファセットについて説明します。 詳細については、「C++ Interop (暗黙の PInvoke) の使用」を参照してください。
次のコード例では、マネージ、アンマネージ の #pragma ディレクティブを使用してマネージ関数とアンマネージ関数を同じファイル内で実装していますが、これらの関数は、別個のファイルに定義された場合も同じように相互運用できます。 アンマネージ関数のみを含むファイルは、/clr (共通言語ランタイムのコンパイル) でコンパイルする必要はありません。
このトピックでは、マネージ関数とアンマネージ関数の間で 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 文字列を受け取ると、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();
}