StructLayout特性允许开发者控制结构在内存中的布局方式。本文将深入探讨StructLayout的用途、选项及其在实际应用中的意义。 1. 什么是StructLayout? StructLayout是一个用于控制结构体或类的内存布局的特性。 StructLayout的选项 StructLayout提供了几个布局选项,通过LayoutKind枚举定义: Sequential(顺序布局): [StructLayout(LayoutKind.Sequential 使用StructLayout的场景 与非托管代码互操作 在P/Invoke和COM互操作中,确保托管结构与非托管结构一致是至关重要的。 通过StructLayout控制字段排列,可以实现更高效的内存使用。 Socket 数据包定义 定义数据包结构 使用StructLayout定义数据包的内存布局,以确保发送和接收的数据格式一致。
/go/tools/cmd/structlayout-pretty@latest shell> go install honnef.co/go/tools/cmd/structlayout-optimize @latest 其中,structlayout 是用来分析数据的,pretty 是用来图形化显示的,optimize 是用来优化建议的,这里就用文章开头优化前的代码给出一个 structlayout-pretty 的例子: shell> structlayout -json . /main.go memAlign | structlayout-pretty structlayout-pretty 虽然 structlayout-pretty 我们可以很直观的看到在哪里存在 padding @latest 把文章开头优化前后的代码分别用 structlayout-svg 生成结果: shell> structlayout -json .
QDC_INCLUDE_HMD = 0x00000020, QDC_VIRTUAL_REFRESH_RATE_AWARE = 0x00000040, } [StructLayout DISPLAYCONFIG_MODE_INFO_TYPE_SOURCE = 1, DISPLAYCONFIG_MODE_INFO_TYPE_TARGET = 2, } [StructLayout public uint id; public uint modeInfoIdx; public uint statusFlags; } [StructLayout ; public DISPLAYCONFIG_PIXELFORMAT pixelFormat; public POINTL position; } [StructLayout DISPLAYCONFIG_PIXELFORMAT_32BPP = 4, DISPLAYCONFIG_PIXELFORMAT_NONGDI = 5, } [StructLayout
所以我再生产环境很少使用这个 工具,一般使用structlayout structlayout[8] structlayout 可以显示struct的布局以及大小,可以输出svg或者json格式的数据。 安装方式 go install honnef.co/go/tools/cmd/structlayout@latest go install honnef.co/go/tools/cmd/structlayout-pretty /svgo/structlayout-svg@latest 用structlayout 分析一下 T1 structlayout -json . /main.go T1 | structlayout-svg >T1.svg Figure 6: T1 Structure Layout 我们可以很清楚的看到有两个padding。 structlayout:显示结构体的内存布局,帮助开发者更直观地理解和优化内存使用。 通过合理使用这些工具,开发者可以在保证程序性能和稳定性的同时,减少内存浪费,提升开发效率。
[StructLayout(LayoutKind.Sequential)] struct StructDeft //C#编译器会自动在上面运用[StructLayout(LayoutKind.Sequential [StructLayout(LayoutKind.Explicit)] [StructLayout(LayoutKind.Explicit)] struct BadStruct { [FieldOffset 如果在struct上运用了[StructLayout(LayoutKind.Explicit)],计算FieldOffset一定要小心,例如我们使用上面BadStruct来进行下面的测试: ? [StructLayout(LayoutKind.Auto)] sizeof(StructAuto)得到的结果是12byte。
", CharSet = CharSet.Auto)] public static extern bool GetCursorPos(out POINT pt); [StructLayout delegate bool MonitorEnumProc(IntPtr monitor, IntPtr hdc, IntPtr lprcMonitor, IntPtr lParam); [StructLayout UnmanagedType.ByValArray, SizeConst = 32)] internal char[] szDevice = new char[32]; } [StructLayout right = (int)r.Right; bottom = (int)r.Bottom; } } [StructLayout
/go/tools/cmd/structlayout-pretty@latest //第三方可视化 go install github.com/ajstarks/svgo/structlayout-svg @latest 上面零大小字段对齐的栗子中 可视化图即是我们使用structlayout和structlayout-svg完成的 //struct M structlayout -json file =~/mywork/workspace/workspace_github/go-snippets/align/align.go M | structlayout-svg -t "align.M" > m.svg //struct N structlayout -json file=~/mywork/workspace/workspace_github/go-snippets/align/align.go N | structlayout-svg -t "align.N" > n.svg 总结 内存对齐主要是CPU可以更高效的访问内存中的数据。
= 0x00000020, Red = 0x00000040, Intensity = 0x00000080 } [StructLayout private struct COORD { short X; short Y; } [StructLayout Left; short Top; short Right; short Bottom; } [StructLayout
[Serializable] [StructLayout(LayoutKind.Auto)] public struct DateTime { } [Serializable] [StructLayout GCHandle.Alloc(new Foobar(), GCHandleType.Pinned); [StructLayout(LayoutKind.Sequential)] public class public class Foobar { public int Foo { get; set; } public double Bar { get; set; } } [StructLayout
private enum MouseMessages { WM_MOUSEMOVE = 0x0200 } [StructLayout private struct POINT { public int x; public int y; } [StructLayout
class MCCustomPrintForm { // Make a static class private MCCustomPrintForm() { } [StructLayout SuppressUnmanagedCodeSecurityAttribute()] internal static extern bool ClosePrinter(IntPtr phPrinter); [StructLayout CharSet.Auto)] internal struct structSize { public Int32 width; public Int32 height; } [StructLayout public Int32 left; public Int32 top; public Int32 right; public Int32 bottom; } [StructLayout FieldOffset(8)] public structSize Size; [FieldOffset(16)] public structRect ImageableArea; }; [StructLayout
modexp.wordpress.com/2019/05/25/windows-injection-finspy/ */ class Program { [StructLayout Reserved3; public IntPtr UniquePid; public IntPtr MoreReserved; } [StructLayout IntPtr fnINOUTSTYLECHANGE2; public IntPtr fnHkINLPMOUSEHOOKSTRUCTEX2; } [StructLayout public const int PROCESSBASICINFORMATION = 0; public const uint WM_COPYDATA = 0x4A; [StructLayout
///
[StructLayout(LayoutKind.Sequential)]
public struct hiH264_DEC_ATTR_S uReserved;
}
///
//消除黑框 } // ------------------- STRUCTS -------------------------------------------- [StructLayout [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] public string ProductName; } [StructLayout [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 34)] public string Info; } [StructLayout TW_STATUS public short ConditionCode; // TwCC public short Reserved; } [StructLayout origin, [In] TwIdentity dest, TwDG dg, TwDAT dat, TwMSG msg, [In, Out] TwPendingXfers pxfr); [StructLayout
按键盘上的空格键就会停止取色,自己复制下来RGB的值 开发思路: 1记录鼠标的坐标 2拾取鼠标下的颜色 开始上代码开发吧 记录鼠标的坐标 public class MyPoint { [StructLayout [StructLayout(LayoutKind.Sequential)] public class POINT { public int x; public [StructLayout(LayoutKind.Sequential)] public class MouseHookStruct { public POINT pt; [StructLayout(LayoutKind.Sequential)] public class KeyboardHookStruct { public int vkCode
", CharSet = CharSet.Auto)]
public static extern bool GetCursorPos(out POINT pt);
[StructLayout Alt、Ctrl等键
#endregion wParam对应的按钮事件
public const int WH_KEYBOARD_LL = 13;
[StructLayout int WM_MBUTTONDBLCLK = 0x209;
///
private static extern bool GetComboBoxInfo(IntPtr hwnd, ref COMBOBOXINFO pcbi); [StructLayout public IntPtr hwndItem; public IntPtr hwndList; } [StructLayout
Console.WriteLine(a); } } } } [StructLayout object and miss the size 如果给 ByValStringStructForSizeMAX_PATH 再加一个字段,将如上代码的 _foo 字段去掉注释,如下面代码 [StructLayout
int WM_MBUTTONDBLCLK = 0x209;
///
PrinterAPI { public class Printer { private Printer() { } ///泥人张版本加强版 #region API声明 [StructLayout public Int32 left; public Int32 top; public Int32 right; public Int32 bottom; } [StructLayout public structSize Size; [FieldOffset(16)] public structRect ImageableArea; }; [StructLayout public int dmReserved1; [MarshalAs(UnmanagedType.U4)] public int dmReserved2; } [StructLayout uint Level, IntPtr pPrinterEnum, uint cbBuf, ref uint pcbNeeded, ref uint pcReturned); [StructLayout