通过 PInvoke 从 C# 到 C++ 的简单结构中的垃圾数据
Garbage data in simple struct from C# to C++ via 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);
总结一下,我确实使用以下代码调用测试函数:
var outputSize = new Common.Size() { Width = 100, Height = 200 };
PluginApi.Test(outputSize);
现在,我希望 C++ 函数中的参数 size 的 Width 和 Height 的值分别为 100 和 200,但我得到的是垃圾编号,更准确地说,Width 和 132313736 0 到高度。
在这种情况下我做错了什么?
它与 C# 中的 public class Size
有关,它可能会为每个对象引入一个 "header",例如,类型信息(如果需要,则为 "vtable pointer")。因此,C# 中对象的内存布局和 C++ 中结构的实例可能不匹配。
在 C# 中使用结构而不是 class 应该可以解决问题。
我有一个简单的 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);
总结一下,我确实使用以下代码调用测试函数:
var outputSize = new Common.Size() { Width = 100, Height = 200 };
PluginApi.Test(outputSize);
现在,我希望 C++ 函数中的参数 size 的 Width 和 Height 的值分别为 100 和 200,但我得到的是垃圾编号,更准确地说,Width 和 132313736 0 到高度。
在这种情况下我做错了什么?
它与 C# 中的 public class Size
有关,它可能会为每个对象引入一个 "header",例如,类型信息(如果需要,则为 "vtable pointer")。因此,C# 中对象的内存布局和 C++ 中结构的实例可能不匹配。
在 C# 中使用结构而不是 class 应该可以解决问题。