C++ 構造体データを C# にエクスポートするのに苦労しています。
3 つの浮動小数点ベクトルを表す次の構造があるとします。
// C++
struct fvec3
{
public:
float x, y, z;
fvec3(float x, float y, float z) : x(x), y(y), z(z) { }
};
// C#
[StructLayout(LayoutKind.Sequential)]
struct fvec3
{
public float x, y, z;
public fvec3(float x, float y, float z)
{
this.x = x;
this.y = y;
this.z = z;
}
}
fvec3
ここで、 C# から C++ への変換を使用したい場合は、次のものを問題なく使用できます。
// C++
__declspec(dllexport) void Import(fvec3 vector)
{
std::cout << vector.x << " " << vector.y << " " << vector.z;
}
// C#
[DllImport("example.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Import(fvec3 vector);
...
Import(new fvec3(1, 2, 3)); // Prints "1 2 3".
ここでの問題は、逆のことを行うことです。つまり、C++fvec3
を C# に戻します。これどうやってするの?多くの C# 実装が次のようなものを使用しているのを見てきました。
// C#
[DllImport("example.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void Export(out fvec3 vector);
...
fvec3 vector;
Export(out vector); // vector contains the value given by C++
Export
しかし、C++関数をどのように記述すればよいでしょうか?
署名と本文の両方について考えられることはすべて試しました。
// Signatures:
__declspec(dllexport) void Export(fvec3 vector)
__declspec(dllexport) void Export(fvec3* vector)
__declspec(dllexport) void Export(fvec3& vector)
// Bodies (with the pointer variants)
vector = fvec3(1, 2, 3);
memcpy(&fvec3(1, 2, 3), &vector, sizeof(fvec3));
*vector = new fvec(1, 2, 3);
これらのいくつかは効果がなく、一部はガベージ値を返し、一部はクラッシュを引き起こします。