Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/135.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
将C#struct的内存大小与C++;结构 我试图在C++和CUDA中创建一个从C结构到非托管代码的自动转换。不幸的是,我似乎无法创建匹配的结构。结构: // C# [StructLayout(LayoutKind.Sequential)] struct DebugComponent { public float4 Float4; public float Float; } // C++ struct CPP_DebugComponent { float4 Float4; float Float; };_C#_C++ - Fatal编程技术网

将C#struct的内存大小与C++;结构 我试图在C++和CUDA中创建一个从C结构到非托管代码的自动转换。不幸的是,我似乎无法创建匹配的结构。结构: // C# [StructLayout(LayoutKind.Sequential)] struct DebugComponent { public float4 Float4; public float Float; } // C++ struct CPP_DebugComponent { float4 Float4; float Float; };

将C#struct的内存大小与C++;结构 我试图在C++和CUDA中创建一个从C结构到非托管代码的自动转换。不幸的是,我似乎无法创建匹配的结构。结构: // C# [StructLayout(LayoutKind.Sequential)] struct DebugComponent { public float4 Float4; public float Float; } // C++ struct CPP_DebugComponent { float4 Float4; float Float; };,c#,c++,C#,C++,使用C#调用将结构的大小计算为20个字节: 我认为差异源于float4结构的定义。CUDA中float4的定义将其与16个字节对齐: // C++ struct __device_builtin__ __builtin_align__(16) float4 { float x, y, z, w; }; // For similar results without the CUDA definition, you can use: // struct __align__(16) float

使用C#调用将结构的大小计算为20个字节:

我认为差异源于float4结构的定义。CUDA中float4的定义将其与16个字节对齐:

// C++
struct __device_builtin__ __builtin_align__(16) float4
{
    float x, y, z, w;
};
// For similar results without the CUDA definition, you can use:
// struct __align__(16) float4
因此,将12字节的填充添加到单个浮点。在C#中,没有这种对齐方式,导致编译器选择4字节的打包。为完整起见,C#(来自ManagedCuda)中的float4定义如下:

我知道我可以通过指定以下属性在C#中人工重新创建大小正确的结构:

 [StructLayout(LayoutKind.Sequential, Size = 32)]
 struct DebugComponent { ... }
但是对于自动代码生成,需要知道结构中所有类型的总和以及一些关于打包和填充的假设。看来我不能用这个扩展结构

我也知道我可以通过使用例如:

来改变C++代码中的填充
#pragma pack(1) 
但我宁愿避免这种解决方案,因为填充会导致性能显著提高

我的问题是:我能模拟非托管填充/打包的行为,使得C结构与C++结构在内存大小上是否对齐?p> 考虑到性能,是否有很好的替代方案来调整结构

以上所有代码示例均在Windows、Visual Studio 2017上运行,并在x64上编译

在我看来,最好的方法是在规范中声明一个与结构大小相同的数组。C或C++对象应该将缓冲区中的元素复制到其数据成员中。

这是最便携的,可以处理C和C++成员之间的填充。由于填充、V表等因素,C和C++类不擅长用数据格式映射1:1。从缓冲区复制还可以处理类中的字符串类和其他非POD类型

还研究“序列化”。

在我看来,最好的方法是在规范中声明一个与结构大小相同的数组。C或C++对象应该将缓冲区中的元素复制到其数据成员中。

这是最便携的,可以处理C和C++成员之间的填充。由于填充、V表等因素,C和C++类不擅长用数据格式映射1:1。从缓冲区复制还可以处理类中的字符串类和其他非POD类型


还研究了“序列化”。结构/结构成员的

填充和对齐不是C++标准的一部分,依赖于实现。意思是,一旦你改变了C++编译器,你就会得到不同的布局(或者可能会得到)。这也是Nvidia保证CUDA只与少数特定编译器配合使用的原因之一


<> P>为了使这个代码转换自动运行,你需要使用C代码> C++中的C++编译器来构造你的C++编译器:遵循与C++编译器相同的规则。对于一般情况来说,这不是不可能的,但可能很难推导出。。。另一方面,对于给定的简单结构,应该有可能导出C++编译器对齐规则。例如,一个基本规则是,最大构件决定整个结构的对齐方式

P>结构与构件的填充和对齐不是C++标准的一部分,依赖于实现。意思是,一旦你改变了C++编译器,你就会得到不同的布局(或者可能会得到)。这也是Nvidia保证CUDA只与少数特定编译器配合使用的原因之一


<> P>为了使这个代码转换自动运行,你需要使用C代码> C++中的C++编译器来构造你的C++编译器:遵循与C++编译器相同的规则。对于一般情况来说,这不是不可能的,但可能很难推导出。。。另一方面,对于给定的简单结构,应该有可能导出C++编译器对齐规则。例如,一个基本规则是,最大构件决定整个结构的对齐方式

AFAIK您仅有的可移植工具是和。如果您要将其映射到原始内存,
System.Runtime.InteropServices.Marshal.SizeOf
是不相关的;
sizeof(DebugComponent)
说什么?sizeof(DebugComponent)(在不安全的代码中)与此结构的Marshal.sizeof相同。您不能通过在开头添加总共消耗12字节的未使用成员变量来伪造填充吗?不过,我并不建议这样做,只是说……当然,C编译器知道Bean关于
\uuuuu内置\uuu对齐(16)
。CLR也没有,这是你的报应。人为增加结构大小不是一个解决办法,关键是结构的起始地址是16的倍数。不可能,您只能在32位代码中对齐到4,在64位代码中对齐到8。您可以使用Marshal.AllocHGlobal()(对齐到8)玩一些小把戏,分配比需要多的8,并在必要时向指针添加8。建议使用C++/CLI,这样您就可以使用
\u aligned\u malloc()
.AFAIK您仅有的可移植工具是和。如果要将其映射到原始内存,
System.Runtime.InteropServices.Marshal.SizeOf
是不相关的;
sizeof(DebugComponent)
说什么?sizeof(DebugComponent)(在不安全的代码中)与此结构的Marshal.sizeof相同。您不能通过在开头添加总共消耗12字节的未使用成员变量来伪造填充吗?不过,我并不建议这样做,只是说……当然,C编译器知道Bean关于
\uuuuu内置\uuu对齐(16)
。CLR也没有,这是你的报应。人为增加结构大小不是一个解决办法,关键是结构的起始地址是一个多重地址
// C#
public struct float4
{
    public float x;
    public float y;
    public float z;
    public float w;
}
 [StructLayout(LayoutKind.Sequential, Size = 32)]
 struct DebugComponent { ... }
#pragma pack(1)