【C#】StructLayout的使用

StructLayout 属性在 C# 中主要用于定义结构体或类在内存中的布局方式,这对于与非托管代码(例如通过 P/Invoke 调用的 Win32 API)进行交互时非常重要。StructLayout 属性位于 System.Runtime.InteropServices 命名空间下。使用此属性可以确保数据结构在内存中按照预期的方式组织,以便正确地传递给非托管代码。

StructLayout 主要参数

  • LayoutKind:定义成员如何排列。

    • Sequential:按顺序排列字段,但会根据平台和类型的默认对齐规则自动插入填充字节。
    • Explicit:允许为每个字段指定确切的偏移量,通常用于精确控制内存布局。
    • Auto:由编译器决定最佳布局方式。
  • Pack:设置结构体成员间的填充字节数,以覆盖默认对齐。值为 1 到 32 的整数,0 表示使用默认对齐。

  • Size:指定整个结构体占用的总字节数。这在需要匹配特定大小的外部结构体时很有用。

  • CharSet:指定字符串成员使用的字符集。选项包括 AnsiUnicodeAuto。影响字符串序列化的方式。

 

StructLayoutAttribute 参数说明

  • LayoutKind:指定结构体成员的布局方式。

    • Sequential:按照成员声明的顺序将它们放置在内存中。每个成员都会根据其类型和平台的默认对齐规则来分配内存。
    • Explicit:允许为每个字段显式地指定偏移量。
    • Auto:由编译器决定最有效的布局方式。
  • Pack:设置结构体成员间的填充字节。这可以用来覆盖默认的对齐规则。例如,如果 Pack = 1,则不会插入任何填充字节;如果 Pack = 2,则确保每个成员从偶数地址开始等。当 Pack = 0 时,表示使用默认的对齐规则,这通常意味着根据数据类型的大小来对齐(如int通常是4字节对齐)。注意,不同的平台可能有不同的默认对齐行为。

其他参数

  • Size:指定整个结构体占用的总字节数。这在某些情况下很有用,比如当知道一个外部定义的结构体的确切大小,并希望C#结构体匹配这个大小时。
  • CharSet:指定字符串成员使用的字符集。选项有 AnsiUnicode 和 Auto。这对于包含字符串或字符数组的结构体尤其重要,因为它会影响这些成员如何被序列化。
  • ValueSize:当 LayoutKind 为 Explicit 时使用,它指定了特定字段所占的字节数。

使用示例

在这个例子中,MyStruct 的成员会紧密排列,中间不会有额外的填充字节。因此,尽管通常情况下 int 类型会在 byte 后面留出3个字节的空隙以保持4字节边界对齐,但这里由于设置了 Pack = 1,所以整个结构体只占用7个字节 (1 + 4 + 2) 而不是常规情况下的8个字节。

using System;
using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MyStruct
{public byte b1; // 1 bytepublic int i1;  // 通常4 bytes,但由于Pack=1,这里没有额外的填充public short s1; // 2 bytes
}class Program
{static void Main(){Console.WriteLine(Marshal.SizeOf<MyStruct>()); // 输出实际大小}
}

请注意,在调整打包值时要小心,因为错误的设置可能导致性能下降或与预期的非托管代码不兼容。

 

顺序布局 (Sequential)

例子中,MyStruct 的所有字段都紧密排列,没有额外的填充字节,因此整个结构体占用 7 字节。

using System;
using System.Runtime.InteropServices;[StructLayout(LayoutKind.Sequential, Pack = 1)]
public struct MyStruct
{public byte b; // 1 bytepublic int i;  // 4 bytespublic short s; // 2 bytes
}class Program
{static void Main(){Console.WriteLine(Marshal.SizeOf<MyStruct>()); // 输出: 7 字节}
}

 

显式布局 (Explicit)

这里使用了 Explicit 布局,并且指定了每个字段的确切位置。注意,即使 Pack=1,显式布局时我们依然能够手动控制每个字段的位置。此外,Size 参数设定了整个结构体的大小为 16 字节,这样在某些情况下可以保证与其他系统兼容。

[StructLayout(LayoutKind.Explicit, Size = 16, Pack = 1)]
public struct ExplicitStruct
{[FieldOffset(0)]     public int X;   // 占用前 4 个字节[FieldOffset(4)]     public int Y;   // 占用接下来的 4 个字节[FieldOffset(8)]     public short Z; // 占用接下来的 2 个字节[FieldOffset(14)]    public byte W;  // 占用最后一个字节
}class Program
{static void Main(){var es = new ExplicitStruct { X = 1, Y = 2, Z = 3, W = 4 };Console.WriteLine(es.X); // 输出: 1Console.WriteLine(es.Y); // 输出: 2Console.WriteLine(es.Z); // 输出: 3Console.WriteLine(es.W); // 输出: 4}
}

 

注意事项

  • 使用 StructLayout 时必须小心,因为错误的配置可能导致性能问题或不正确的数据交换。
  • 对于跨平台的应用程序,请考虑不同操作系统可能有不同的默认对齐规则。
  • 在处理显式布局时,确保所有的字段都没有重叠,否则会导致未定义行为。
  • 当与非托管代码交互时,务必查阅相关文档来确定正确的布局配置。

 

 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/54102.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言、Eazy_X——五子棋

//五子棋#include<graphics.h>#define board_size 20 #define pixel 600 int pr pixel / board_size; char board_data[board_size][board_size]; char current_piece o; int count 0;//检测指定玩家是否获胜 bool CheckWin(char c) {int i, j;//检查行for (i 0; i &…

线程池:线程池的实现 | 日志

&#x1f308;个人主页&#xff1a; 南桥几晴秋 &#x1f308;C专栏&#xff1a; 南桥谈C &#x1f308;C语言专栏&#xff1a; C语言学习系列 &#x1f308;Linux学习专栏&#xff1a; 南桥谈Linux &#x1f308;数据结构学习专栏&#xff1a; 数据结构杂谈 &#x1f308;数据…

【git lfs 问题记录】

报错如下 WARNING: error running /usr/lib/git-core/git ‘config’ ‘–includes’ ‘–global’ ‘–replace-all’ ‘filter.lfs.smudge’ ‘git-lfs smudge – %f’: ‘error: could not write config file /root/.gitconfig: Device or resource busy’ ‘exit status 4…

基于STM32的智能家居交互终端:使用FreeRTOS与MQTT协议的流程设计

一、项目概述 简要介绍项目的目标和用途 随着智能家居的普及&#xff0c;家庭智能交互终端成为提升居住体验的重要设备。本文将介绍一个基于STM32的家庭智能交互终端的设计与实现&#xff0c;该终端能够通过触摸屏、语音识别和传感器数据采集等功能&#xff0c;提供家庭环境监…

数值计算的程序设计问题举例

### 数值计算的程序设计问题 #### 1. 结构静力分析计算 **涉及领域**&#xff1a;工程力学、建筑工程 **主要问题**&#xff1a;线性代数方程组&#xff08;Linear Algebraic Equations&#xff09; **解释说明**&#xff1a; 在结构静力分析中&#xff0c;我们需要解决复杂的…

linux系统解压zip文件名乱码

这是 zip 格式本身的缺陷导致的。zip 格式并没有指定文件名的编码格式&#xff0c;在压缩和解压时均使用操作系统本地编码&#xff0c;Windows 下简体中文为 GBK/GB2312 编码&#xff0c;Linux 下为 UTF-8 编码&#xff0c;两者不一致就造成了乱码。 解决方案&#xff1a; 如…

C++:类中的特殊关键字,运算重载符

1.My_string类中重载以下的运算符&#xff1a; 、[] 、>、<、、>、<、&#xff01;、、输入输出(>>、<<) 主函数&#xff1a; #include <iostream> #include "my_string.h"using namespace std;int main() {My_string s1("cat…

基于SpringBoot+Vue的个人健康管理系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码、微信小程序源码 精品专栏&#xff1a;…

【STM32-HAL库】自发电型风速传感器(使用STM32F407ZGT6)(附带工程下载链接)

一、自发电型风速传感器介绍 自发电型风速传感器&#xff0c;也称为风力发电型风速传感器或无源风速传感器&#xff0c;是一种不需要外部电源即可工作的风速测量设备。这种传感器通常利用风力来驱动内部的发电机构&#xff0c;从而产生电能来供电测量风速的传感器部分。以下是自…

GS-SLAM论文阅读笔记--GEVO

前言 这篇文章看着就让人好奇。众所周知&#xff0c;高斯是一个很不错的建图方法&#xff0c;但是本文的题目居然是只用高斯进行单目VO&#xff0c;咱也不知道这是怎么个流程&#xff0c;看了一下作者来自于MIT&#xff0c;说不定是个不错的工作&#xff0c;那就具体看看吧&am…

springboot实战学习(10)(ThreadLoacl优化获取用户详细信息接口)(重写拦截器afterCompletion()方法)

接着学习。之前的博客的进度&#xff1a;完成用户模块的注册接口的开发以及注册时的参数合法性校验、也基本完成用户模块的登录接口的主逻辑的基础上、JWT令牌"的组成与使用、完成了"登录认证"&#xff08;生成与验证JWT令牌&#xff09;以及完成获取用户详细信…

APISIX 联动雷池 WAF 实现 Web 安全防护

Apache APISIX 是一个动态、实时、高性能的云原生 API 网关&#xff0c;提供了负载均衡、动态上游、灰度发布、服务熔断、身份认证、可观测性等丰富的流量管理功能。 雷池是由长亭科技开发的 WAF 系统&#xff0c;提供对 HTTP 请求的安全请求&#xff0c;提供完整的 API 管理和…

解决 Sqoop 导入 Hive 时时间字段精度丢失问题

目录 一、背景介绍 二、问题描述 三、问题原因 四、解决方案 五、结论 一、背景介绍 介绍 Sqoop 数据导入过程&#xff0c;尤其是从 MySQL 导入 Hive 的场景。说明 MySQL 和 Hive 的数据类型差异&#xff0c;特别是 DATETIME 和 TIMESTAMP 类型的精度问题。 二、问题描述…

MySQL深度分页

在现代Web应用中&#xff0c;数据的逐步展示除了增强用户体验外&#xff0c;还有效提高了系统性能。然而&#xff0c;随着数据集的不断增大&#xff0c;尤其是在数据库表中记录数量达到百万甚至千万级别时&#xff0c;处理深度分页&#xff08;即访问较后页的数据&#xff09;就…

JetLinks物联网平台微服务化系列文章介绍

橙蜂智能公司致力于提供先进的人工智能和物联网解决方案&#xff0c;帮助企业优化运营并实现技术潜能。公司主要服务包括AI数字人、AI翻译、AI知识库、大模型服务等。其核心价值观为创新、客户至上、质量、合作和可持续发展。 橙蜂智农的智慧农业产品涵盖了多方面的功能&#x…

【CKA】二、节点管理-设置节点不可用

2、节点管理-设置节点不可用 1. 考题内容&#xff1a; 2. 答题思路&#xff1a; 先设置节点不可用&#xff0c;然后驱逐节点上的pod 这道题就两条命令&#xff0c;直接背熟就行。 也可以查看帮助 kubectl cordon -h kubectl drain -h 参数详情&#xff1a; –delete-empty…

YOLO11震撼发布!

非常高兴地向大家介绍 Ultralytics YOLO系列的新模型&#xff1a; YOLO11&#xff01; YOLO11 在以往 YOLO 模型基础上带来了一系列强大的功能和优化&#xff0c;使其速度更快、更准确、用途更广泛。主要改进包括 增强了特征提取功能&#xff0c;从而可以更精确地捕捉细节以更…

在树莓派上基于 LNMP 搭建 Nextcloud

原文链接&#xff1a;https://blog.iyatt.com/?p17296 环境 树莓派CM4raspios 20240704 Debian 12 arm64 搭建 LNMP 环境 安装 Nginx sudo apt update sudo apt install -y nginx安装 php 及功能组件支持 参考&#xff1a;https://docs.nextcloud.com/server/latest/adm…

网关的作用及其高可用性设计详解

引言 在现代分布式系统架构中&#xff0c;网关&#xff08;Gateway&#xff09;是一个关键组件。它作为客户端与后端服务之间的桥梁&#xff0c;不仅提供了请求路由、负载均衡、安全认证、流量控制等功能&#xff0c;还能够保护后端服务的安全和稳定性。网关的设计和高可用性对…

EXCEL图片链接快速批量转成图片

EXCEL图片链接快速批量转成图片 直接上图 "<table><img src"&C1&" height50 width50></table>"复制F列到txt文件&#xff0c;暂时放置 全选复制&#xff0c;然后插入一列&#xff0c;粘贴到新的一列中去如图一所示。 ps&…