Mapping unmanaged data to a managed structure in .NET.

I spent many hours working with unmanaged code, and the platform is invoked in .NET. The code below shows what puzzles me how unmanaged data maps to a managed object in .NET.

In this example, I'm going to use the RECT structure:

C ++ RECT implementation (unmanaged Win32 API)

typedef struct _RECT { LONG left; LONG top; LONG right; LONG bottom; } RECT, *PRECT; 

C # RECT Implementation (Managed .NET / C #)

 [StructLayout(LayoutKind.Sequential)] public struct RECT { public int left, top, right, bottom; } 

Ok, so my C # equivalent should work, right? I mean, all variables are in the same order as the C ++ structure, and use the same variable names.

My assumption is that LayoutKind.Sequential means that unmanaged data is mapped to a managed object in the same sequence as in a C ++ structure. that is, data will be displayed, starting from the left, then the top, then the right, then from the bottom.

On this basis, I should be able to change my C # structure ...

C # RECT implementation (a bit clean)

 [StructLayout(LayoutKind.Sequential)] public struct Rect //I've started by giving it a .NET compliant name { private int _left, _top, _right, _bottom; // variables are no longer directly accessible. /* I can now access the coordinates via properties */ public Int32 Left { get { return _left; } set { this._left = value; } } public Int32 Top { get { return _top; } set { this._top = value; } } public Int32 Right { get { return _right; } set { this._right = value; } } public Int32 Bottom { get { return _bottom; } set { this._bottom = value; } } } 

So what happens if the variables are declared in the wrong order? Presumably this screws up the coordinates because they will no longer display on the right thing?

 public struct RECT { public int top, right, bottom, left; } 

Assuming it would look like this:

top = left

right = top

bottom = right

left = bottom

So my question is simple: I proceed with the assumption that I can change the managed structure in terms of the access specifier of each variable and even the name of the variable, but I can not change the order of the variables?

+7
source share
4 answers

If you really want to reorder your member variables, you can do this using FieldOffsetAttribute . Just makes it a little less readable.

You also need to set the LayoutKind.Explicit to LayoutKind.Explicit to indicate that you set the offsets yourself.

Example:

 [StructLayout(LayoutKind.Explicit)] public struct RECT { [FieldOffset(4)] public int top; [FieldOffset(8)] public int right; [FieldOffset(12)] public int bottom; [FieldOffset(0)] public int left; } 
+7
source

Yes, it seems your thinking is fine. StructLayout(LayoutKind.Sequential) is the default value applied to C # struct , so you don't even need to do this. But if you want to have a different order of fields, you can do this using StructLayout(LayoutKind.Explicite) , and then apply the FieldOffset attribute to each field - this is a much better approach as you make an explanation of what is implied and is no longer up to you which can be easily changed, as the order of field definition.

Take a look at the MSDN sample: StructLayoutAttribute Class , and it should be clearer. In addition, create a sample application in C ++ and C # and play with it so that it hangs it - it will be of great benefit to you.

+2
source

The default mapping of a struct in C # is the default LayoutKind.Sequential . This prevents the compiler from optimizing memory by interchanging variables and ensuring proper mapping.

However, you can tell the compiler about a different order of variables using LayoutKind.Explicit and FieldOffsetAttribute :

 [StructLayout(LayoutKind.Explicit)] public struct Rect { [FieldOffset(8)] public int right; [FieldOffset(4)] public int top; [FieldOffset(0)] public int left; [FieldOffset(12)] public int bottom; } 

The FieldOffsetAttribute value indicates the position of the byte in the structure of the beginning of the variable.

+1
source

I proceed from my assumption that I can change the managed structure in terms of the access specifier of each variable and even the name of the variable, but I can not change the order of the variables?

Yes, that's right. Neither the access specifier nor the variable name affects the way the structure is structured.

0
source

All Articles