方法: C++ Interop を使用して構造体をマーシャリングする

このトピックでは、Visual C++ の相互運用性の一面を示します。 詳細については、「C++ Interop (暗黙の PInvoke) の使用」を参照してください。

managed、unmanaged #pragma ディレクティブを使用して、同じファイルにマネージド関数とアンマネージド関数を実装する方法を次のコード例に示します。これらの関数は、別々のファイルで定義されている場合でも同じ方法で相互運用されます。 アンマネージド関数のみを含むファイルを、/clr (共通言語ランタイムのコンパイル) を使用してコンパイルする必要はありません。

例: マネージド関数からアンマネージド関数に構造体を渡す

次の例では、値と参照の両方によって、マネージド関数からアンマネージド関数に構造体を渡す例を示しています。 この例の構造体には単純な組み込みデータ型 (「Blittable 型と非 Blittable 型」を参照) しか含まれていないので、特別なマーシャリングは必要ありません。 ポインターを含んだ構造体など、blittable 以外の構造体をマーシャリングするには、「方法: C++ Interop を使用して埋め込みポインターをマーシャリングする」を参照してください。

// PassStruct1.cpp
// compile with: /clr

#include <stdio.h>
#include <math.h>

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

#pragma unmanaged

struct Location {
   int x;
   int y;
};

double GetDistance(Location loc1, Location loc2) {
   printf_s("[unmanaged] loc1(%d,%d)", loc1.x, loc1.y);
   printf_s(" loc2(%d,%d)\n", loc2.x, loc2.y);

   double h = loc1.x - loc2.x;
   double v = loc1.y - loc2.y;
   double dist = sqrt( pow(h,2) + pow(v,2) );

   return dist;
}

void InitLocation(Location* lp) {
   printf_s("[unmanaged] Initializing location...\n");
   lp->x = 50;
   lp->y = 50;
}

#pragma managed

int main() {
   Location loc1;
   loc1.x = 0;
   loc1.y = 0;

   Location loc2;
   loc2.x = 100;
   loc2.y = 100;

   double dist = GetDistance(loc1, loc2);
   Console::WriteLine("[managed] distance = {0}", dist);

   Location loc3;
   InitLocation(&loc3);
   Console::WriteLine("[managed] x={0} y={1}", loc3.x, loc3.y);
}

例: アンマネージド関数からマネージド関数に構造体を渡す

次の例では、値と参照の両方によって、アンマネージド関数からマネージド関数に構造体を渡す例を示しています。 この例の構造体には単純な組み込みデータ型 (「Blittable 型と非 Blittable 型」を参照) しか含まれていないので、特別なマーシャリングは必要ありません。 ポインターを含んだ構造体など、blittable 以外の構造体をマーシャリングするには、「方法: C++ Interop を使用して埋め込みポインターをマーシャリングする」を参照してください。

// PassStruct2.cpp
// compile with: /clr
#include <stdio.h>
#include <math.h>
using namespace System;

// native structure definition
struct Location {
   int x;
   int y;
};

#pragma managed

double GetDistance(Location loc1, Location loc2) {
   Console::Write("[managed] got loc1({0},{1})", loc1.x, loc1.y);
   Console::WriteLine(" loc2({0},{1})", loc2.x, loc2.y);

   double h = loc1.x - loc2.x;
   double v = loc1.y = loc2.y;
   double dist = sqrt( pow(h,2) + pow(v,2) );

   return dist;
}

void InitLocation(Location* lp) {
   Console::WriteLine("[managed] Initializing location...");
   lp->x = 50;
   lp->y = 50;
}

#pragma unmanaged

int UnmanagedFunc() {
   Location loc1;
   loc1.x = 0;
   loc1.y = 0;

   Location loc2;
   loc2.x = 100;
   loc2.y = 100;

   printf_s("(unmanaged) loc1=(%d,%d)", loc1.x, loc1.y);
   printf_s(" loc2=(%d,%d)\n", loc2.x, loc2.y);

   double dist = GetDistance(loc1, loc2);
   printf_s("[unmanaged] distance = %f\n", dist);

   Location loc3;
   InitLocation(&loc3);
   printf_s("[unmanaged] got x=%d y=%d\n", loc3.x, loc3.y);

    return 0;
}

#pragma managed

int main() {
   UnmanagedFunc();
}

関連項目

C++ Interop (暗黙の PInvoke) の使用