我正在寻找一种快速方法来序列化由基本值类型和字符串组成的自定义结构。
使用C ++ CLI固定结构实例和目标数组的指针,然后对数据进行memcpy对所有值类型都很有效。但是,如果我包含任何引用类型(如字符串),那么我得到的只是引用地址。
预期尽可能多,否则结构将不可能具有固定的结构。我想也许,如果我把字符串固定大小,它可能会把它放在结构中。添加< VBFixedString(256)>字符串声明没有实现。
还有什么能将实际数据放在结构中吗?
答案 0 :(得分:0)
固定托管对象并记忆内容永远不会满足您的需求。任何托管对象,无论是String
,字符数组还是其他任何东西都会显示为参考,您只需获取内存位置即可。
如果我在两行之间阅读,听起来你需要调用一些C或C ++(而不是C ++ / CLI)代码,并传递一个类似于此的C结构:
struct UnmanagedFoo
{
int a_number;
char a_string[256];
};
如果是这种情况,那么我可以通过设置自动编组来解决这个问题。以下是您如何定义该结构以便正确编组的方法。 (我在这里使用C#语法,但它应该很容易转换为VB.net语法。)
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public struct ManagedFoo
{
public int a_number;
[MarshalAs(UnmanagedType.ByValTStr, SizeConst=256)]
public string a_string;
}
说明:
StructLayout
(LayoutKind.Sequential)
指定字段应按声明的顺序排列。默认的LayoutKind Auto
允许在编译器需要时重新排序字段。CharSet=CharSet.Ansi
指定要编组的字符串类型。您可以指定CharSet.Ansi
在C ++端获取char
字符串,或CharSet.Unicode
在C ++中获取wchar_t
字符串。MarshalAs
(UnmanagedType.ByValTStr)
指定结构内联的字符串,这就是您所询问的内容。还有其他几种具有不同语义的字符串类型,请参阅MSDN上的UnmanagedType
页面以获取说明。SizeConst=256
指定字符数组的大小。请注意,这指定了字符数(或执行数组时,数组元素数),不字节数。现在,这些marshal属性是.Net中内置封送程序的指令,您可以直接从VB.Net代码调用它。要使用它,请调用Marshal.StructureToPtr
从.Net对象转到非托管内存,并Marshal.PtrToStructure
从非托管内存转到.Net对象。 MSDN有一些调用这两种方法的好例子,看看链接的页面。
等等,C ++ / CLI怎么样?是的,您可以使用C ++ / CLI从.Net对象编组到C结构。如果您的结构太复杂而无法用MarshalAs
属性表示,那么它非常适合这样做。在这种情况下,您可以执行以下操作:声明您的.Net结构,就像上面列出的那样,没有MarshalAs
或StructLayout
。同样声明C结构,普通和普通,也如上所列。当你需要从一个切换到另一个时,按字段字段复制字段,而不是一个大的memcpy。是的,所有基本类型的字段(整数,双精度等)都是重复的output.a_number = input.a_number
,但这是正确的方法。