我正在尝试将Jim Kyle在90年代早期编写的btrieve代码升级到VB.NET,并且遇到了联合结构的问题。旧的C代码如下:
typedef struct {
union {
struct {
PGPTR PgSeq; // 00 - page number
int Usage; // 04 - match with usage count
int Version; // 06 - version code, <0 if owned
} v5;
struct {
int RecSig; // 00 - 'FC'
int SeqNbr; // 02 - always binary zeroes
long Usage; // 04 - usage count
} v6;
} r1;
int PagSize; // 08 - in bytes
} FCRTOP;
到目前为止,我有:
<StructLayout(LayoutKind.Explicit)> _
Structure FCRTOP
<FieldOffset(0)> Public PgSeq As PGPTR
<FieldOffset(4)> Public Usage As Short
<FieldOffset(6)> Public Version As Short
<FieldOffset(0)> Public RecSig As Short
<FieldOffset(2)> Public SeqNbr As Short
<FieldOffset(4)> Public Usage As Integer
End Structure
我遇到的一个问题是VB.NET不喜欢两个具有相同名称的结构变量(用法)。如果在C示例中(v5和v6)完成了重叠字段与唯一结构名称的分组,我缺少什么?
感谢您的帮助!
答案 0 :(得分:7)
答案完全取决于你在做什么:
如果您正在创建托管界面,则应该知道结构成员的命名将被忽略。这是元素的顺序和大小,这很重要。但是,这不是你的问题,因为你只是处理C定义结构的方式与VB.NET(和其他.NET语言)的方式之间的阻抗不匹配。由于union
关键字只允许您将更大的结构分解为变量的逻辑块而不将子结构定义为独立的数据结构,因此需要进行一些按摩才能将其转换为.NET,这不允许这样的事情(同样,结构体不是在基于参考的面向对象语言(如VB.NET和C#)中封装信息的主要方法)。你必须采用子结构并将它们自己定义为结构,然后定义一个变量作为子结构,作为外部结构上的常规成员。
(顺便说一句,如果您按顺序声明成员,则无需使用StructLayoutKind.Explicit
;使用Sequential
会使其更容易阅读,如果它们已经按照正确的顺序排列。)< / p>
在那个有点冗长的回应之后,你正在寻找这样的东西:
<StructLayout(LayoutKind.Sequential)> _
Structure StructV5
Public PgSeq As PGPTR
Public Usage As Short
Public Version As Short
End Structure
<StructLayout(LayoutKind.Sequential)> _
Structure StructV6
Public RecSig As Short
Public SeqNbr As Short
Public Usage As Integer
End Structure
<StructLayout(LayoutKind.Explicit)> _
Structure FCRTOP
<FieldOffset(0)>Public V5 as StructV5
<FieldOffset(0)>Public V6 as StructV6
<FieldOffset(8)>Public PagSize as Short
End Structure
您的另一个选择是保持您的结构不变(并添加PagSize
成员),只需在Usage
内更改v6
的名称即可。但是,采用这种方法(使用显式结构声明)将为您提供更有意义的语法。
答案 1 :(得分:0)
VB.NET绝对没有这样的功能,所以我认为最好的办法是尝试以与.NET类型系统兼容的方式捕捉工会理念的“精神”。
免责声明:我对C的了解很少,所以我可能会误解C 中的工会的目的是什么。如果是这种情况,从我的建议中可以看出这一点。
所以,我认为你真正想要的是Structure
包含64位,可以代表你的示例C代码中的v5
或v6
,再加上PageSize
的16位}。为了实现这一点,我要做的是存储4个Short
值,并根据需要将它们组合起来(注意:我在下面概述的内容将是一个不可变类型;如果你需要使用公共读/写字段那么如果可能的话,我不知道如何实现这一点:
Structure FCRTOP
Private a As Short
Private b As Short
Private c As Short
Private d As Short
Public ReadOnly PageSize As Short
' Possibly two constructors, one accepting PGTR, Short Short, Short, '
' the other accepting Short, Short, Integer, Short '
Public ReadOnly Property V5 As V5
Get
Return New V5(a, b, c, d)
End Get
End Property
Public ReadOnly Property V6 As V6
Get
Return New V5(a, b, c, d)
End Get
End Property
End Structure
Structure V5
' Constructor accepting 4 Short values '
' Properties that expose these values as PGTR, Short, Short'
End Structure
Stucture V6
' Constructor similar to V5 above '
' Properties that expose these values as Short, Short, Integer'
End Structure