S
sexauthor
I'm converting a VB6 application over that called a 3rd party DLL with
specific data structures. The VB6 code defined custom types for those
data structures (ie: one with the specific data types, then one as a
word array, and one as a byte array, for use in generating CRCs etc)
and would LSet one to the other to copy data over.
Naturally we can't do that in .NET. I've done lots of reading in the
interoperability books and the closest thing I've been able to come up
with is:
Public Const dmq_s_user_data As Integer = 20 ' bytes
<StructLayout(LayoutKind.Explicit)> Structure dmq_user_struct
' <FieldOffset(0)> <VBFixedString(dmq_s_user_data)> Dim
dmq_b_user_data() As Byte
' <FieldOffset(0)> <MarshalAs(UnmanagedType.ByValArray,
sizeconst:=dmq_s_user_data, arraysubtype:=UnmanagedType.AsAny)> Dim
dmq_b_user_data() As Byte
' <FieldOffset(0)> <MarshalAs(UnmanagedType.ByValTStr,
sizeconst:=dmq_s_user_data)> Dim dmq_b_user_data() As Byte
<FieldOffset(0)> Dim dmq_l_user_1 As Integer
<FieldOffset(4)> Dim dmq_l_user_2 As Integer
<FieldOffset(8)> Dim dmq_l_user_3 As Integer
<FieldOffset(12)> Dim dmq_l_user_4 As Integer
<FieldOffset(16)> Dim dmq_l_user_5 As Integer
Public Sub Initialize()
' ReDim dmq_b_user_data(dmq_s_user_data)
End Sub
End Structure 'dmq_user_struct
You can see there's the data itself, plus commented out ways of
defining access to the data as a byte array. You can compile any of
these to try, but you'll get an exception when you run it because
arrays are a reference and you can't overlap references and values in
structs like this.
That's a huge problem for me. It turns out that in C# 2.0 you could
define an array of bytes in-place with a "fixed" keyword. So in a
structure you could have ...
fixed byte dmq_b_user_data(dmq_s_user_data)
And it would translate to something like ...
byte dmq_b_user_data_1
byte dmq_b_user_data_2
byte dmq_b_user_data_3
... dmq_s_user_data
Instead of being just a pointer to that array. I haven't been able to
find anything in VB.NET, or any similar language construct to
"fixed". I always get a pointer, and so I can't use that.
I've read other suggestions to specifically define each byte as a
reference type, but that's not going to work well for me seeing as
some of these structures are really large and it would be too
cumbersome.
The other suggestion was define one structure with the named fields,
and one structure of just the byte array, and use
Marshal.StructureToPtr and Marshal.Copy to copy the bytes from one to
the other. I can do that, but this is a performance application and I
don't want to unless I have to.
Any comments, suggestions, hints, gripes from people with the same
problem? I'd be particularly interested if there's been a "fixed" in-
place array type introduced in VB.NET somewhere that I'm not aware
of.
Thanks.
specific data structures. The VB6 code defined custom types for those
data structures (ie: one with the specific data types, then one as a
word array, and one as a byte array, for use in generating CRCs etc)
and would LSet one to the other to copy data over.
Naturally we can't do that in .NET. I've done lots of reading in the
interoperability books and the closest thing I've been able to come up
with is:
Public Const dmq_s_user_data As Integer = 20 ' bytes
<StructLayout(LayoutKind.Explicit)> Structure dmq_user_struct
' <FieldOffset(0)> <VBFixedString(dmq_s_user_data)> Dim
dmq_b_user_data() As Byte
' <FieldOffset(0)> <MarshalAs(UnmanagedType.ByValArray,
sizeconst:=dmq_s_user_data, arraysubtype:=UnmanagedType.AsAny)> Dim
dmq_b_user_data() As Byte
' <FieldOffset(0)> <MarshalAs(UnmanagedType.ByValTStr,
sizeconst:=dmq_s_user_data)> Dim dmq_b_user_data() As Byte
<FieldOffset(0)> Dim dmq_l_user_1 As Integer
<FieldOffset(4)> Dim dmq_l_user_2 As Integer
<FieldOffset(8)> Dim dmq_l_user_3 As Integer
<FieldOffset(12)> Dim dmq_l_user_4 As Integer
<FieldOffset(16)> Dim dmq_l_user_5 As Integer
Public Sub Initialize()
' ReDim dmq_b_user_data(dmq_s_user_data)
End Sub
End Structure 'dmq_user_struct
You can see there's the data itself, plus commented out ways of
defining access to the data as a byte array. You can compile any of
these to try, but you'll get an exception when you run it because
arrays are a reference and you can't overlap references and values in
structs like this.
That's a huge problem for me. It turns out that in C# 2.0 you could
define an array of bytes in-place with a "fixed" keyword. So in a
structure you could have ...
fixed byte dmq_b_user_data(dmq_s_user_data)
And it would translate to something like ...
byte dmq_b_user_data_1
byte dmq_b_user_data_2
byte dmq_b_user_data_3
... dmq_s_user_data
Instead of being just a pointer to that array. I haven't been able to
find anything in VB.NET, or any similar language construct to
"fixed". I always get a pointer, and so I can't use that.
I've read other suggestions to specifically define each byte as a
reference type, but that's not going to work well for me seeing as
some of these structures are really large and it would be too
cumbersome.
The other suggestion was define one structure with the named fields,
and one structure of just the byte array, and use
Marshal.StructureToPtr and Marshal.Copy to copy the bytes from one to
the other. I can do that, but this is a performance application and I
don't want to unless I have to.
Any comments, suggestions, hints, gripes from people with the same
problem? I'd be particularly interested if there's been a "fixed" in-
place array type introduced in VB.NET somewhere that I'm not aware
of.
Thanks.