CF2 vs CF1 Struct Marshal Compatibility Problem

I

indiekiduk

Hi, does anyone why the code below would produce the following result?

2.0.6129
56

1.0.4292
48

I know that CF2 has better support for struct marshalling due to it
including the FieldOffset and Pack attributes which CF1 lacks. However
my application is in CF1 for WM5 end user niceness. However, since WM6
now includes CF2 and not CF1 my application isn't compatible because
of this problem. Is there anyway I can fix this sample code to run on
both CF1 and CF2 properly?

I should point out the resulting problem is that when you access the
Marshal from native to this struct in CF2 the data gets mangled
because some of the offsets are wrong. I understand packing and I
appreciate that the MAC struct gets filled up to 8 bytes, thats ok,
but what is CF2 doing different?

(Note if I install CF1 onto the WM6 PDA gives the correct value of 48,
but I'm trying to avoid doing that. The fact that Visual Studio does
it automatically might cause headaches for some developers when they
release.)

#region Using directives

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;

#endregion
using System.Runtime.InteropServices;

namespace StructTester
{
/// <summary>
/// Summary description for form.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Label label1;
private MenuItem menuItem1;
private Label label2;
/// <summary>
/// Main menu for the form.
/// </summary>
private System.Windows.Forms.MainMenu mainMenu1;

public Form1()
{
InitializeComponent();
label2.Text = Environment.Version.ToString();
Test t = new Test();
label1.Text = Marshal.SizeOf(t).ToString();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.label1 = new System.Windows.Forms.Label();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.label2 = new System.Windows.Forms.Label();
//
// mainMenu1
//
this.mainMenu1.MenuItems.Add(this.menuItem1);
//
// label1
//
this.label1.Location = new System.Drawing.Point(3, 40);
this.label1.Size = new System.Drawing.Size(152, 22);
this.label1.Text = "label1";
//
// menuItem1
//
this.menuItem1.Text = "Close";
this.menuItem1.Click += new
System.EventHandler(this.menuItem1_Click);
//
// label2
//
this.label2.Location = new System.Drawing.Point(3, 3);
this.label2.Size = new System.Drawing.Size(152, 22);
this.label2.Text = "label2";
//
// Form1
//
this.ClientSize = new System.Drawing.Size(176, 180);
this.Controls.Add(this.label1);
this.Controls.Add(this.label2);
this.Menu = this.mainMenu1;
this.Text = "Form1";

}

#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new Form1());
}

private void menuItem1_Click(object sender, EventArgs e)
{
Close();
}
}

//cf1 48
//cf2 56
[StructLayout(LayoutKind.Sequential)]
struct Test
{
int a;
MAC m;
SSID s;
}

[StructLayout(LayoutKind.Sequential)]
struct MAC
{
byte b1, b2, b3, b4, b5, b6;
}

[StructLayout(LayoutKind.Sequential)]
public struct SSID
{
public uint SsidLength; // length of SSID field below,
in bytes;
// this can be zero.
// SSID array of 32 UCHAR
public long Ssid_0;
public long Sssid_1, Ssid_2, Ssid_3; // SSID
information field
}
}
 
I

indiekiduk

Hi, does anyone why the code below would produce the following result?

2.0.6129
56

1.0.4292
48

I know that CF2 has better support for struct marshalling due to it
including the FieldOffset and Pack attributes which CF1 lacks. However
my application is in CF1 for WM5 end user niceness. However, since WM6
now includes CF2 and not CF1 my application isn't compatible because
of this problem. Is there anyway I can fix this sample code to run on
both CF1 and CF2 properly?

I should point out the resulting problem is that when you access the
Marshal from native to this struct in CF2 the data gets mangled
because some of the offsets are wrong. I understand packing and I
appreciate that the MAC struct gets filled up to 8 bytes, thats ok,
but what is CF2 doing different?

(Note if I install CF1 onto the WM6 PDA gives the correct value of 48,
but I'm trying to avoid doing that. The fact that Visual Studio does
it automatically might cause headaches for some developers when they
release.)

#region Using directives

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;

#endregion
using System.Runtime.InteropServices;

namespace StructTester
{
/// <summary>
/// Summary description for form.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Label label1;
private MenuItem menuItem1;
private Label label2;
/// <summary>
/// Main menu for the form.
/// </summary>
private System.Windows.Forms.MainMenu mainMenu1;

public Form1()
{
InitializeComponent();
label2.Text = Environment.Version.ToString();
Test t = new Test();
label1.Text = Marshal.SizeOf(t).ToString();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.label1 = new System.Windows.Forms.Label();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.label2 = new System.Windows.Forms.Label();
//
// mainMenu1
//
this.mainMenu1.MenuItems.Add(this.menuItem1);
//
// label1
//
this.label1.Location = new System.Drawing.Point(3, 40);
this.label1.Size = new System.Drawing.Size(152, 22);
this.label1.Text = "label1";
//
// menuItem1
//
this.menuItem1.Text = "Close";
this.menuItem1.Click += new
System.EventHandler(this.menuItem1_Click);
//
// label2
//
this.label2.Location = new System.Drawing.Point(3, 3);
this.label2.Size = new System.Drawing.Size(152, 22);
this.label2.Text = "label2";
//
// Form1
//
this.ClientSize = new System.Drawing.Size(176, 180);
this.Controls.Add(this.label1);
this.Controls.Add(this.label2);
this.Menu = this.mainMenu1;
this.Text = "Form1";

}

#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new Form1());
}

private void menuItem1_Click(object sender, EventArgs e)
{
Close();
}
}

//cf1 48
//cf2 56
[StructLayout(LayoutKind.Sequential)]
struct Test
{
int a;
MAC m;
SSID s;
}

[StructLayout(LayoutKind.Sequential)]
struct MAC
{
byte b1, b2, b3, b4, b5, b6;
}

[StructLayout(LayoutKind.Sequential)]
public struct SSID
{
public uint SsidLength; // length of SSID field below,
in bytes;
// this can be zero.
// SSID array of 32 UCHAR
public long Ssid_0;
public long Sssid_1, Ssid_2, Ssid_3; // SSID
information field
}

}

Oh here is a simpler example:

struct Test
{
byte b;
long l;
}

1.0.4292.0
12

2.0.6129.0
16

So is it CF1 which is wrong for not doing the default packing of 8?
 
G

Guest

1. Who says the default packing should be 8? I'd assume 4 if I assumed
anything
2. If you care about packing, then you should *never* rely on the default
and manually make sure all members are aligned as you want. This is the
case even in C/C++.


--
Chris Tacke - Embedded MVP
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--



Hi, does anyone why the code below would produce the following result?

2.0.6129
56

1.0.4292
48

I know that CF2 has better support for struct marshalling due to it
including the FieldOffset and Pack attributes which CF1 lacks. However
my application is in CF1 for WM5 end user niceness. However, since WM6
now includes CF2 and not CF1 my application isn't compatible because
of this problem. Is there anyway I can fix this sample code to run on
both CF1 and CF2 properly?

I should point out the resulting problem is that when you access the
Marshal from native to this struct in CF2 the data gets mangled
because some of the offsets are wrong. I understand packing and I
appreciate that the MAC struct gets filled up to 8 bytes, thats ok,
but what is CF2 doing different?

(Note if I install CF1 onto the WM6 PDA gives the correct value of 48,
but I'm trying to avoid doing that. The fact that Visual Studio does
it automatically might cause headaches for some developers when they
release.)

#region Using directives

using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;

#endregion
using System.Runtime.InteropServices;

namespace StructTester
{
/// <summary>
/// Summary description for form.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Label label1;
private MenuItem menuItem1;
private Label label2;
/// <summary>
/// Main menu for the form.
/// </summary>
private System.Windows.Forms.MainMenu mainMenu1;

public Form1()
{
InitializeComponent();
label2.Text = Environment.Version.ToString();
Test t = new Test();
label1.Text = Marshal.SizeOf(t).ToString();
}

/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}

#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.label1 = new System.Windows.Forms.Label();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.label2 = new System.Windows.Forms.Label();
//
// mainMenu1
//
this.mainMenu1.MenuItems.Add(this.menuItem1);
//
// label1
//
this.label1.Location = new System.Drawing.Point(3, 40);
this.label1.Size = new System.Drawing.Size(152, 22);
this.label1.Text = "label1";
//
// menuItem1
//
this.menuItem1.Text = "Close";
this.menuItem1.Click += new
System.EventHandler(this.menuItem1_Click);
//
// label2
//
this.label2.Location = new System.Drawing.Point(3, 3);
this.label2.Size = new System.Drawing.Size(152, 22);
this.label2.Text = "label2";
//
// Form1
//
this.ClientSize = new System.Drawing.Size(176, 180);
this.Controls.Add(this.label1);
this.Controls.Add(this.label2);
this.Menu = this.mainMenu1;
this.Text = "Form1";

}

#endregion

/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new Form1());
}

private void menuItem1_Click(object sender, EventArgs e)
{
Close();
}
}

//cf1 48
//cf2 56
[StructLayout(LayoutKind.Sequential)]
struct Test
{
int a;
MAC m;
SSID s;
}

[StructLayout(LayoutKind.Sequential)]
struct MAC
{
byte b1, b2, b3, b4, b5, b6;
}

[StructLayout(LayoutKind.Sequential)]
public struct SSID
{
public uint SsidLength; // length of SSID field below,
in bytes;
// this can be zero.
// SSID array of 32 UCHAR
public long Ssid_0;
public long Sssid_1, Ssid_2, Ssid_3; // SSID
information field
}

}

Oh here is a simpler example:

struct Test
{
byte b;
long l;
}

1.0.4292.0
12

2.0.6129.0
16

So is it CF1 which is wrong for not doing the default packing of 8?
 
I

indiekiduk

1. Who says the default packing should be 8? I'd assume 4 if I assumed
anything
2. If you care about packing, then you should *never* rely on the default
and manually make sure all members are aligned as you want. This is the
case even in C/C++.

--
Chris Tacke - Embedded MVP
OpenNETCF Consulting
Managed Code in the Embedded Worldwww.opennetcf.com
--


Hi, does anyone why the code below would produce the following result?
2.0.6129
56
1.0.4292
48
I know that CF2 has better support for struct marshalling due to it
including the FieldOffset and Pack attributes which CF1 lacks. However
my application is in CF1 for WM5 end user niceness. However, since WM6
now includes CF2 and not CF1 my application isn't compatible because
of this problem. Is there anyway I can fix this sample code to run on
both CF1 and CF2 properly?
I should point out the resulting problem is that when you access the
Marshal from native to this struct in CF2 the data gets mangled
because some of the offsets are wrong. I understand packing and I
appreciate that the MAC struct gets filled up to 8 bytes, thats ok,
but what is CF2 doing different?
(Note if I install CF1 onto the WM6 PDA gives the correct value of 48,
but I'm trying to avoid doing that. The fact that Visual Studio does
it automatically might cause headaches for some developers when they
release.)
#region Using directives
using System;
using System.Drawing;
using System.Collections;
using System.Windows.Forms;
using System.Data;
#endregion
using System.Runtime.InteropServices;
namespace StructTester
{
/// <summary>
/// Summary description for form.
/// </summary>
public class Form1 : System.Windows.Forms.Form
{
private Label label1;
private MenuItem menuItem1;
private Label label2;
/// <summary>
/// Main menu for the form.
/// </summary>
private System.Windows.Forms.MainMenu mainMenu1;
public Form1()
{
InitializeComponent();
label2.Text = Environment.Version.ToString();
Test t = new Test();
label1.Text = Marshal.SizeOf(t).ToString();
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
#region Windows Form Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.mainMenu1 = new System.Windows.Forms.MainMenu();
this.label1 = new System.Windows.Forms.Label();
this.menuItem1 = new System.Windows.Forms.MenuItem();
this.label2 = new System.Windows.Forms.Label();
//
// mainMenu1
//
this.mainMenu1.MenuItems.Add(this.menuItem1);
//
// label1
//
this.label1.Location = new System.Drawing.Point(3, 40);
this.label1.Size = new System.Drawing.Size(152, 22);
this.label1.Text = "label1";
//
// menuItem1
//
this.menuItem1.Text = "Close";
this.menuItem1.Click += new
System.EventHandler(this.menuItem1_Click);
//
// label2
//
this.label2.Location = new System.Drawing.Point(3, 3);
this.label2.Size = new System.Drawing.Size(152, 22);
this.label2.Text = "label2";
//
// Form1
//
this.ClientSize = new System.Drawing.Size(176, 180);
this.Controls.Add(this.label1);
this.Controls.Add(this.label2);
this.Menu = this.mainMenu1;
this.Text = "Form1";
}
#endregion
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
Application.Run(new Form1());
}
private void menuItem1_Click(object sender, EventArgs e)
{
Close();
}
}
//cf1 48
//cf2 56
[StructLayout(LayoutKind.Sequential)]
struct Test
{
int a;
MAC m;
SSID s;
}
[StructLayout(LayoutKind.Sequential)]
struct MAC
{
byte b1, b2, b3, b4, b5, b6;
}
[StructLayout(LayoutKind.Sequential)]
public struct SSID
{
public uint SsidLength; // length of SSID field below,
in bytes;
// this can be zero.
// SSID array of 32 UCHAR
public long Ssid_0;
public long Sssid_1, Ssid_2, Ssid_3; // SSID
information field
}
}
Oh here is a simpler example:
struct Test
{
byte b;
long l;
}


So is it CF1 which is wrong for not doing the default packing of 8?

Thanks for the reply, I read it here:
http://msdn.microsoft.com/msdnmag/issues/06/01/NETMatters/default.aspx
"The default packing size for a managed structure is 8."

But oops, since I'm using it in an unmanaged way you are right I
shouldn't rely on any default. I wasn't aware it was an issue because
I hadn't seen it mentioned in any p/invoke articles. But now thinking
about x64 it probably is a serious thing to think about. Anyway, I was
using CF1 so the default is the only option if you want to marshal
structs and since CF1 and CF2 run on the same native platform I'd
expect to see the same behaviour. Although now I notice that alot of
the OpenNETCF code doesn't marshal structs from unmanaged memory into
structs at all - it does byte reads with offsets instead. I guess I'll
do this the next time I do a CF1 p/invoke library. For now I a found a
temporary solution which is to use ints instead of longs in the
struct, then the packing doesn't mess up on CF2. e.g.

struct Test
{
byte b;
int i;
int j;
}

1.0.4292.0
12

2.0.6129.0
12

This solution works for me because the ints are only a place holder
for a chunk of 8 bytes. So I do byte* b = (byte*)test.i; inside a
fixed statement, thats for i and j. Then when I come to read any
following fields in a struct, for example if there was an int x after
the j, then offset is correct. Remember in CF1 you can't put a byte[]
inside a struct.

I'd be interested to know why a long in a struct affects the packing
in CF2 if anyone knows?
 
G

Guest

Thanks for the reply, I read it here:
http://msdn.microsoft.com/msdnmag/issues/06/01/NETMatters/default.aspx
"The default packing size for a managed structure is 8."

I've not read that, but my guess would be that it's 8 for a 64-bit system.
Since CE can't use 64-bit I've never run into it, but it's likely safe to
assume that a 64-bit system can only read a QWORD from an address divisible
by 8.
But oops, since I'm using it in an unmanaged way you are right I
shouldn't rely on any default. I wasn't aware it was an issue because
I hadn't seen it mentioned in any p/invoke articles. But now thinking
about x64 it probably is a serious thing to think about.

I'm surprised to see the apparent 8-byte alignment in CF 2 - the only thing
I can think is they did it for some FFx compatibility. There are no CE
devices that use 8-bit, so it seems inefficient and needless to force
8-byte.
Anyway, I was
using CF1 so the default is the only option if you want to marshal
structs and since CF1 and CF2 run on the same native platform I'd
expect to see the same behaviour. Although now I notice that alot of
the OpenNETCF code doesn't marshal structs from unmanaged memory into
structs at all - it does byte reads with offsets instead.

Yes, the CF 1.0 Marshaler was less than stellar, so we used a mechanism that
was guaranteed to work. I still prefer it in CF 2.0 in fact. It's a bit
more work to write, but you know what's happening. THere are still plenty
of scenarios that the CF 2.0 Marshaler can't handle.
I guess I'll
do this the next time I do a CF1 p/invoke library. For now I a found a
temporary solution which is to use ints instead of longs in the
struct, then the packing doesn't mess up on CF2. e.g.

struct Test
{
byte b;
int i;
int j;
}

1.0.4292.0
12

2.0.6129.0
12

Yes, those numbers are what I'd expect.
This solution works for me because the ints are only a place holder
for a chunk of 8 bytes. So I do byte* b = (byte*)test.i; inside a
fixed statement, thats for i and j. Then when I come to read any
following fields in a struct, for example if there was an int x after
the j, then offset is correct. Remember in CF1 you can't put a byte[]
inside a struct.

But you can always marshal an array of bytes (which is all a struct is)
under any version.
I'd be interested to know why a long in a struct affects the packing
in CF2 if anyone knows?

I'd be interested to know as well. More interesting is why CF 1.0 and CF
2.0 differ.


--
Chris Tacke - Embedded MVP
OpenNETCF Consulting
Managed Code in the Embedded World
www.opennetcf.com
--
 
I

indiekiduk

Thanks for the reply, I read it here:
http://msdn.microsoft.com/msdnmag/issues/06/01/NETMatters/default.aspx
"The default packing size for a managed structure is 8."

I've not read that, but my guess would be that it's 8 for a 64-bit system.
Since CE can't use 64-bit I've never run into it, but it's likely safe to
assume that a 64-bit system can only read a QWORD from an address divisible
by 8.
But oops, since I'm using it in an unmanaged way you are right I
shouldn't rely on any default. I wasn't aware it was an issue because
I hadn't seen it mentioned in any p/invoke articles. But now thinking
about x64 it probably is a serious thing to think about.

I'm surprised to see the apparent 8-byte alignment in CF 2 - the only thing
I can think is they did it for some FFx compatibility. There are no CE
devices that use 8-bit, so it seems inefficient and needless to force
8-byte.
Anyway, I was
using CF1 so the default is the only option if you want to marshal
structs and since CF1 and CF2 run on the same native platform I'd
expect to see the same behaviour. Although now I notice that alot of
the OpenNETCF code doesn't marshal structs from unmanaged memory into
structs at all - it does byte reads with offsets instead.

Yes, the CF 1.0 Marshaler was less than stellar, so we used a mechanism that
was guaranteed to work. I still prefer it in CF 2.0 in fact. It's a bit
more work to write, but you know what's happening. THere are still plenty
of scenarios that the CF 2.0 Marshaler can't handle.


I guess I'll
do this the next time I do a CF1 p/invoke library. For now I a found a
temporary solution which is to use ints instead of longs in the
struct, then the packing doesn't mess up on CF2. e.g.
struct Test
{
byte b;
int i;
int j;
}

2.0.6129.0
12

Yes, those numbers are what I'd expect.
This solution works for me because the ints are only a place holder
for a chunk of 8 bytes. So I do byte* b = (byte*)test.i; inside a
fixed statement, thats for i and j. Then when I come to read any
following fields in a struct, for example if there was an int x after
the j, then offset is correct. Remember in CF1 you can't put a byte[]
inside a struct.

But you can always marshal an array of bytes (which is all a struct is)
under any version.
I'd be interested to know why a long in a struct affects the packing
in CF2 if anyone knows?

I'd be interested to know as well. More interesting is why CF 1.0 and CF
2.0 differ.

--
Chris Tacke - Embedded MVP
OpenNETCF Consulting
Managed Code in the Embedded Worldwww.opennetcf.com
--

Thanks for all the feedback. I tried it on the full framework and it
give 16 when a long is in the struct so that is likely the proper
behaviour and the bug was actually in the CF1 Marhsaller.

Even still, if anyone knows an article about why a long in a struct
differs from 2 ints I'd like to read about that.
 
I

Ilya Tumanov [MS]

AFAIK that was a fix in NETCF V2 marshaling so it would match native
compiler alignment.

That is, if you have same structure declared in native code alignment should
match in V2 and be broken in V1.


--
Best regards,

Ilya

This posting is provided "AS IS" with no warranties, and confers no rights.

*** Want to find answers instantly? Here's how... ***

1. Go to
http://groups-beta.google.com/group/microsoft.public.dotnet.framework.compactframework?hl=en
2. Type your question in the text box near "Search this group" button.
3. Hit "Search this group" button.
4. Read answer(s).

Thanks for the reply, I read it here:
http://msdn.microsoft.com/msdnmag/issues/06/01/NETMatters/default.aspx
"The default packing size for a managed structure is 8."

I've not read that, but my guess would be that it's 8 for a 64-bit
system.
Since CE can't use 64-bit I've never run into it, but it's likely safe to
assume that a 64-bit system can only read a QWORD from an address
divisible
by 8.
But oops, since I'm using it in an unmanaged way you are right I
shouldn't rely on any default. I wasn't aware it was an issue because
I hadn't seen it mentioned in any p/invoke articles. But now thinking
about x64 it probably is a serious thing to think about.

I'm surprised to see the apparent 8-byte alignment in CF 2 - the only
thing
I can think is they did it for some FFx compatibility. There are no CE
devices that use 8-bit, so it seems inefficient and needless to force
8-byte.
Anyway, I was
using CF1 so the default is the only option if you want to marshal
structs and since CF1 and CF2 run on the same native platform I'd
expect to see the same behaviour. Although now I notice that alot of
the OpenNETCF code doesn't marshal structs from unmanaged memory into
structs at all - it does byte reads with offsets instead.

Yes, the CF 1.0 Marshaler was less than stellar, so we used a mechanism
that
was guaranteed to work. I still prefer it in CF 2.0 in fact. It's a bit
more work to write, but you know what's happening. THere are still
plenty
of scenarios that the CF 2.0 Marshaler can't handle.


I guess I'll
do this the next time I do a CF1 p/invoke library. For now I a found a
temporary solution which is to use ints instead of longs in the
struct, then the packing doesn't mess up on CF2. e.g.
struct Test
{
byte b;
int i;
int j;
}

2.0.6129.0
12

Yes, those numbers are what I'd expect.
This solution works for me because the ints are only a place holder
for a chunk of 8 bytes. So I do byte* b = (byte*)test.i; inside a
fixed statement, thats for i and j. Then when I come to read any
following fields in a struct, for example if there was an int x after
the j, then offset is correct. Remember in CF1 you can't put a byte[]
inside a struct.

But you can always marshal an array of bytes (which is all a struct is)
under any version.
I'd be interested to know why a long in a struct affects the packing
in CF2 if anyone knows?

I'd be interested to know as well. More interesting is why CF 1.0 and CF
2.0 differ.

--
Chris Tacke - Embedded MVP
OpenNETCF Consulting
Managed Code in the Embedded Worldwww.opennetcf.com
--

Thanks for all the feedback. I tried it on the full framework and it
give 16 when a long is in the struct so that is likely the proper
behaviour and the bug was actually in the CF1 Marhsaller.

Even still, if anyone knows an article about why a long in a struct
differs from 2 ints I'd like to read about that.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top