次の方法で共有


方法: C++ Interop を使用して Unicode 文字列をマーシャリングする

このトピックでは、Visual C++ の相互運用性の一面を示します。 詳細については、「C++ Interop (暗黙の 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++ Interop (暗黙の PInvoke) の使用