如果结构未初始化,returns 按值构造的 C++ 函数的 C# PInvoke 崩溃
C# PInvoke of C++ function that returns struct by value crashes if the struct is left uninitialized
在 this post 中,他们使用了一个 bool,它可以在平台之间具有可变大小。这里没有这样的事情。该结构是 blittable 的。
如果结构未初始化,方法会在 return 上崩溃 - 我不确定为什么。假设我想 return 具有随机内容的结构。仅仅是因为这是无效的 C++ 吗?
C++:
struct H { uint32_t x; };
extern "C" __declspec(dllexport) H _cdecl GetH() {
std::cout << "get-h called" << std::endl;
H h{5}; // works if this is used
// H h; // fails if this is used
return h;
}
C#:
[StructLayout(LayoutKind.Sequential)]
public struct H {
[MarshalAs(UnmanagedType.U4)]
public UInt32 X;
}
[DllImport("mydll.dll", EntryPoint = "GetH", CallingConvention = CallingConvention.Cdecl)]
private static extern H GetH();
void Test() {
H h = GetH();
Console.WriteLine(h.X);
}
没有初始化器的输出 h{5}:
get-h called
Test.exe exited with code -2147483645
问题是代码是在调试模式下编译的,运行时检查(缺少)变量初始化设置了断点。由于这是 P 调用的并且我附加到调用 C#,我看不到 C++ 中发生了什么,它只是退出并显示错误代码 0x80000003,正如@HansPassant 指出的那样。一旦我在 Visual Studio 中启用本机代码调试,异常就变得清晰,进程不再突然终止。
此外,发布模式编译取消了运行时检查(/RTC 编译标志),这在发布模式下不会成为问题。所以 return 一个未初始化的结构在实践中确实有效。
在 this post 中,他们使用了一个 bool,它可以在平台之间具有可变大小。这里没有这样的事情。该结构是 blittable 的。
如果结构未初始化,方法会在 return 上崩溃 - 我不确定为什么。假设我想 return 具有随机内容的结构。仅仅是因为这是无效的 C++ 吗?
C++:
struct H { uint32_t x; };
extern "C" __declspec(dllexport) H _cdecl GetH() {
std::cout << "get-h called" << std::endl;
H h{5}; // works if this is used
// H h; // fails if this is used
return h;
}
C#:
[StructLayout(LayoutKind.Sequential)]
public struct H {
[MarshalAs(UnmanagedType.U4)]
public UInt32 X;
}
[DllImport("mydll.dll", EntryPoint = "GetH", CallingConvention = CallingConvention.Cdecl)]
private static extern H GetH();
void Test() {
H h = GetH();
Console.WriteLine(h.X);
}
没有初始化器的输出 h{5}:
get-h called
Test.exe exited with code -2147483645
问题是代码是在调试模式下编译的,运行时检查(缺少)变量初始化设置了断点。由于这是 P 调用的并且我附加到调用 C#,我看不到 C++ 中发生了什么,它只是退出并显示错误代码 0x80000003,正如@HansPassant 指出的那样。一旦我在 Visual Studio 中启用本机代码调试,异常就变得清晰,进程不再突然终止。
此外,发布模式编译取消了运行时检查(/RTC 编译标志),这在发布模式下不会成为问题。所以 return 一个未初始化的结构在实践中确实有效。