Length of a structure containing double members

  • Thread starter Thread starter marco_segurini
  • Start date Start date
M

marco_segurini

Hi,

From my VB program I call a C++ function that gets a structure pointer
like parameter. The structure has a field that contains the structure
length and other fields.

My problem is that each 'double' fields get 12 bytes instead of 8 so
the structure length results wrong.

'----Sample

Imports System.Runtime.InteropServices

Module Module1
<StructLayout(LayoutKind.Sequential)> Public Structure
structDoubleSeq
Public size As Integer
Public d As Double
End Structure

<StructLayout(LayoutKind.Sequential)> Public Structure
structDoubleSeqUn
Public size As Integer
<MarshalAs(UnmanagedType.R8)> Public d As Double
End Structure

<StructLayout(LayoutKind.Explicit)> Public Structure
structDoubleExpl
<FieldOffset(0)> Public size As Integer
<FieldOffset(4)> Public d As Double
End Structure

Sub Main()
Dim strSeq As structDoubleSeq
strSeq.size = Marshal.SizeOf(GetType(structDoubleSeq))
'WRONG: the size is set to 16

Dim strSeqUn As structDoubleSeqUn
strSeqUn.size = Marshal.SizeOf(GetType(structDoubleSeqUn))
'WRONG: the size is set to 16

Dim strExpl As structDoubleExpl
strExpl.size = Marshal.SizeOf(GetType(structDoubleExpl))
'OK: this size is set to 12
End Sub
End Module

'----- End Sample

Using <StructLayout(LayoutKind.Explicit)> all work fine but I like to
work with <StructLayout(LayoutKind.Sequential)> that is less error
prone in case of structure with a lot of members.

Is there any directive to 'compact' the structure?

Is there any directive to 'compact' a single field (like double)?

TIA.

Marco.
 
marco_segurini said:
Sub Main()
Dim strSeq As structDoubleSeq
strSeq.size = Marshal.SizeOf(GetType(structDoubleSeq))
'WRONG: the size is set to 16

It is not wrong. See the docs for the Sequantial enum member.

<StructLayout(LayoutKind.Sequential, pack:=1)> _
Public Structure structDoubleSeq
Public size As Integer
Public d As Double
End Structure

When you don't specify the Pack field, data is packed.... it's described in
the help for StructLayoutAttribute.Pack.
 
The default structure packing is 8. This means that your doubles are being
aligned on 8 byte addresses giving you an extra 4 bytes of padding between
the Integer and the Double. Change your StructLayout attribute to include a
Pack setting of 4.

<System.Runtime.InteropServices.StructLayout(LayoutKind.Sequential, Pack :=
4)> ...
 
(e-mail address removed) (marco_segurini) wrote in message
FOUND!
<StructLayout(LayoutKind.Sequential)> Public Structure
structDoubleSeq
Public size As Integer
Public d As Double
End Structure

My problem depends on this two points:

1) The structure above is aligned to 8 bytes: so even it size is 12
bytes the alignment makes it 16 bytes long (this is the sample I
described before).

2) In my original structure I have more than one double field: I found
that a double field must be 8-bytes-aligned. From this follows that

<StructLayout(LayoutKind.Sequential)> Public Structure
structMoreDoubles1
Public l1 As Integer
Public d1 As Double
Public l2 As Integer
Public d2 As Double
Public l3 As Integer
Public d3 As Double
End Structure

has length 48

whereas

<StructLayout(LayoutKind.Sequential)> Public Structure
structMoreDoubles2
Public l1 As Integer
Public l2 As Integer
Public l3 As Integer
Public d1 As Double
Public d2 As Double
Public d3 As Double
End Structure

has length 40

---------------

In this case the Len(<variable>) function returns 36 for both
structMoreDoubles1 and structMoreDoubles2 that is the value that I
expect in my dll function but this is wrong for me because the
structures are not really packed into 36 bytes --> PORTING FROM VB6 TO
VB.NET PROBLEM.

by.
Marco.
 
Hi,

From my VB program I call a C++ function that gets a structure pointer
like parameter. The structure has a field that contains the structure
length and other fields.

My problem is that each 'double' fields get 12 bytes instead of 8 so
the structure length results wrong.

Is there any directive to 'compact' the structure?

Sounds like an alignment issue... Check out the Pack field of the
StructLayoutAttribute class. It lets you specify the packing :)

Tom Shelton
 
Back
Top