通过PInvoke

时间:2017-10-21 19:37:18

标签: c# c++ pinvoke

我有一个简单的Size结构,定义为

#pragma pack(push, 8)
struct Size final
{
public:
  std::int32_t Width = 0;
  std::int32_t Height = 0;
};
#pragma pack(pop)

在C ++中和

[StructLayout(LayoutKind.Sequential, Pack = 8)]
public class Size
{
    public System.Int32 Width { get; set; }
    public System.Int32 Height { get; set; }
}

在C#中。

现在,我正在尝试创建一个C#Size对象并将其发送到C ++代码,因为我在C ++中有这个功能

extern "C" {
__declspec(dllexport) auto Test(Common::Size size) -> void;
}

auto Test(const Common::Size size) -> void
{
    // Do something
}

和一个PInvoke C#函数将其称为:

[DllImport("mydll.dll", CallingConvention = CallingConvention.Cdecl, EntryPoint = "Test")]
public static extern void Test(Common.Size size);

为了把它包起来,我用这段代码调用Test函数:

var outputSize = new Common.Size() { Width = 100, Height = 200 };
PluginApi.Test(outputSize);

现在,我期望的是C ++函数中的参数大小分别为100和200的宽度和高度,但我得到的是垃圾数,更准确地说,132313736用于宽度,0到高度。

在这种情况下,我做错了什么?

1 个答案:

答案 0 :(得分:0)

它与C#中的[[-1] [-2, -2] [-2, -1, -2] [-3, 0, -1, -3 [-3, 2, 1, -1, -3] [-4, 4, 3, 1, -1, -4] [-4, 7, 6, 4, 2, -1, -4] [-5, 10, 9, 7, 5, 2, -1, -5] [-5, 14, 13, 11, 9, 6, 3, -1, -5] [-6, 18, 17, 15, 13, 10, 7, 3, -1, -6] [-6, 23, 22, 20, 18, 15, 12, 8, 4, -1, -6] [-7, 28, 27, 25, 23, 20, 17, 13, 9, 4, -1, -7] [-7, 34, 33, 31, 29, 26, 23, 19, 15, 10, 5, -1, -7] [-8, 40, 39, 37, 35, 32, 29, 25, 21, 16, 11, 5, -1, -8] [-8, 47, 46, 44, 42, 39, 36, 32, 28, 23, 18, 12, 6, -1, -8] [-9, 54, 53, 51, 49, 46, 43, 39, 35, 30, 25, 19, 13, 6, -1, -9] [-9, 62, 61, 59, 57, 54, 51, 47, 43, 38, 33, 27, 21, 14, 7, -1, -9] [-10, 70, 69, 67, 65, 62, 59, 55, 51, 46, 41, 35, 29, 22, 15, 7, -1, -10]] 有关,它可能会为每个对象引入一个“标题”,例如,类型信息(如果需要,可以使用“vtable指针”)。因此,c#中对象的内存布局和C ++中struct的实例可能不匹配。

在C#中使用结构而不是类可以解决问题。