次の方法で共有


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

このトピックでは、C++ Interop を使用して ANSI 文字列を渡す方法を説明します。ただし、.NET Framework の String は、文字列を Unicode 形式で表すため、ANSI に変換する手順が別途必要です。 その他の文字列型との相互運用の詳細については、次のトピックを参照してください。

次のコード例では、マネージ、アンマネージ の #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++ Interop (暗黙の PInvoke) の使用