C#sizeof用法

C#中sizeof方法

用于获取 值类型 的字节大小。https://msdn.microsoft.com/zh-cn/library/eahchzkf(VS.80).aspx

对于所有其他类型(包括 struct),sizeof 运算符只能在不安全代码块中使用。虽然可以使用 SizeOf 方法,但该方法返回的值和 sizeof 返回的值并不总是相同的。Marshal.SizeOf 在已封送处理类型后返回大小,而 sizeof 返回公共语言运行库分配的大小(包括任何空白)。

计算struct大小

    public struct StructTest
    {
        public char a;
        public int b;
        public char c;
        public double d;      
        public char e;
    }

输出

32位:32

64位:32

这个很奇怪!!!不太懂

内存对齐。计算机系统对基本类型在内存中存放的位置进行限制,要求这些数据的首地址是某个数的倍数(4或8),这个数叫做对齐模数。ANSI C标准并没有规定,相邻的变量在内存中一定要相邻,内存对齐问题有编译器自行灵活处理。32位系统最大对齐模数是4,因为一次最大读取32位。

对齐原因:

(1)平台原因:不是所有的硬件平台都能访问任意地址上的任意数据,某些硬件平台只能在某些地址处取某些特定类型的数据,否则抛出硬件异常。

(2)性能原因:数据结构应尽可能的在自然边界上对齐。为了访问未对齐的内存,处理器需要做两次内存访问,而对齐的内存访问仅需要异常访问。

对齐规则:

1)结构体或union联合的数据成员,第一个数据成员是要放在offset==0的地方,如果遇上子成员,要根据子成员的类型存放在对应的整数倍的地址上。

2)如果结构体作为成员,则要找到这个结构体中的最大元素,然后从这个最大成员的整数倍地址开始存储。

如果想忽略为了对齐而填充补上的部分,可以使用[StructLayout]特性,可以选择Auto、Explicit、Sequential三种对齐方式

    [StructLayout(LayoutKind.Auto)] 
    public struct StructTest
    {
        public char a;
        public int b;
        public char c;
        public double d;      
        public char e;
    }

输出

32位:20=a(2)+b(4)+c(2)+d(4+4)+e(2)+2,补齐,对齐模数=4

64位:24=a(2)+b(4)+c(2)+d(8)+e(2)+6,补齐,对齐模数=8

计算枚举类型enum大小

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine(sizeof(MyEnum1));
            Console.WriteLine(sizeof(MyEnum2));
            Console.WriteLine(sizeof(MyEnum3));
            Console.ReadKey();
        }
        enum MyEnum1
        {
        }
        enum MyEnum2
        {
            C1 = 1,
        }
        enum MyEnum3
        {
            C1 = 1,
            C2 = 2
        }
    }

返回值均为4,枚举是为了更好的定义常量,优点是常量值是自动生成的,这些常量可以用int范围数表示,所以sizeof(enumType)=sizeof(int)=4。

Marshal.SizeOf()方法

https://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.marshal.sizeof(v=vs.110).aspx

返回类的非托管大小(以字节为单位)。

  • 2
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
对于使用得力扫描枪扫描二维码,你可以使用以下步骤在C#中实现: 1. 确保你的得力扫描枪已经连接到计算机,并且被识别为HID(Human Interface Device)设备。 2. 使用Windows API来读取扫描枪的输入数据。你可以通过使用`RegisterRawInputDevices`函数来注册输入设备,并使用`WM_INPUT`消息来接收输入数据。 下面是一个基本的示例代码,演示了如何使用C#来处理得力扫描枪的输入数据: ```csharp using System; using System.Runtime.InteropServices; using System.Windows.Forms; class Program { private const int WM_INPUT = 0x00FF; private const int RID_INPUT = 0x10000003; private const int RIDEV_INPUTSINK = 0x00000100; private const int RIDEV_DEVNOTIFY = 0x00002000; [StructLayout(LayoutKind.Sequential)] struct RAWINPUTDEVICELIST { public IntPtr hDevice; public int dwType; } [DllImport("user32.dll")] static extern uint GetRawInputDeviceList(IntPtr pRawInputDeviceList, ref uint uiNumDevices, uint cbSize); [DllImport("user32.dll")] static extern bool RegisterRawInputDevices(RAWINPUTDEVICELIST[] pRawInputDeviceList, uint uiNumDevices, uint cbSize); [DllImport("user32.dll")] static extern uint GetRawInputData(IntPtr hRawInput, uint uiCommand, IntPtr pData, ref uint pcbSize, uint cbSizeHeader); static void Main() { // 注册输入设备 RAWINPUTDEVICELIST[] rawInputDeviceList = new RAWINPUTDEVICELIST[1]; rawInputDeviceList[0].dwType = RID_INPUT; rawInputDeviceList[0].hDevice = IntPtr.Zero; if (!RegisterRawInputDevices(rawInputDeviceList, 1, (uint)Marshal.SizeOf<RAWINPUTDEVICELIST>())) { Console.WriteLine("无法注册输入设备。"); return; } // 创建窗口来接收输入消息 NativeWindow window = new NativeWindow(); window.CreateHandle(new CreateParams()); // 循环接收输入消息 while (true) { Application.DoEvents(); } } protected override void WndProc(ref Message m) { if (m.Msg == WM_INPUT) { // 读取输入数据 uint size = 0; GetRawInputData(m.LParam, RID_INPUT, IntPtr.Zero, ref size, (uint)Marshal.SizeOf<RAWINPUTHEADER>()); IntPtr buffer = Marshal.AllocHGlobal((int)size); try { GetRawInputData(m.LParam, RID_INPUT, buffer, ref size, (uint)Marshal.SizeOf<RAWINPUTHEADER>()); // 在这里处理扫描枪的输入数据 // 解析二维码数据并进行相关操作 // 例如,你可以通过ZXing库来解码二维码 // 你可以在这里将二维码数据传递给其他方法进行处理 ProcessQRCodeData(buffer); } finally { Marshal.FreeHGlobal(buffer); } } base.WndProc(ref m); } private void ProcessQRCodeData(IntPtr buffer) { // 在这里处理扫描枪输入的二维码数据 // 解析二维码并进行相关操作 // 例如,你可以使用ZXing库来解码二维码 // 以下是一个使用ZXing库解码二维码的示例 // 你需要安装ZXing.Net库,通过NuGet包管理器安装 ZXing.BarcodeReader barcodeReader = new ZXing.BarcodeReader(); ZXing.Result result = barcodeReader.Decode(new Bitmap(/* 这里是图像数据来源 */)); if (result != null) { string decodedText = result.Text; Console.WriteLine("解码结果: " + decodedText); } else { Console.WriteLine("未能解码二维码。"); } } } ``` 请注意,上述代码只是一个基本示例,你需要根据实际情况进行适当的修改和调整。在代码中,我们使用`WM_INPUT`消息来接收扫描枪的输入数据,并通过`RegisterRawInputDevices`函数注册输入设备。然后,我们创建了一个窗口来接收输入消息,并在`WndProc`方法中处理输入数据。你可以在`ProcessQRCodeData`方法中解析扫描枪输入的二维码数据。 希望这可以帮助到你!如果你有任何其他问题,请随时提问。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值