提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档
VB.net小技巧——VB.net中的结构体和共用体
- 前言
- 结构体和共用体的定义
- 一个完整的程序示例
- 下位机和上位机浮点传输示例
- 下位机示例
- 上位机示例
前言
在C语言中,有一种类型名为共用体,关键字为union,它与结构体十分类似,但是它所有的数值全都指向同一个指针。也就是说,当你修改共用体内的某一个数据时,其他数据也会同时改变。
这个类型的好处,在于可以存储某种不确定的数据对象,等到稍后再来分析出该对象的用途。
这个对于数制的转换和传输非常有用。
在之前的VB6.0中,我使用的是CopyMemory的方法,但在现在的VB.net中这里有了新的变化,在这里记录一下
结构体和共用体的定义
union MyUnion
{char b; //单字节整数,在c语言中用char类型来表示单字节整数short s; //双字节整数int i; //四字节整数
}
在 .net 中使用联合体,我们只需要声明一个普通的结构体,然后在结构体上使用属性描述即可。
结构体:
Structure MyStructDim b0 As ByteDim b1 As ByteDim b2 As ByteDim b3 As ByteDim s As ShortDim us As UShortDim i As IntegerDim ui As UIntegerEnd Structure
联合体:
Imports System.Runtime.InteropServices'引入运行时非托管数据管理服务<StructLayout(LayoutKind.Explicit)> _Structure MyUnion<FieldOffset(0)> Dim b0 As Byte<FieldOffset(1)> Dim b1 As Byte<FieldOffset(2)> Dim b2 As Byte<FieldOffset(3)> Dim b3 As Byte<FieldOffset(0)> Dim s As Short<FieldOffset(2)> Dim us As UShort<FieldOffset(0)> Dim i As Integer<FieldOffset(0)> Dim ui As UIntegerEnd Structure
可以看出 .NET 中的联合体更强大,因为它甚至可以指定某个数值的偏移位置。
一个完整的程序示例
Imports System.Runtime.InteropServices '引入运行时非托管数据管理服务Public Class Form1<StructLayout(LayoutKind.Explicit)> _Structure MyUnion<FieldOffset(0)> Dim b0 As Byte<FieldOffset(1)> Dim b1 As Byte<FieldOffset(2)> Dim b2 As Byte<FieldOffset(3)> Dim b3 As Byte<FieldOffset(0)> Dim s As Short<FieldOffset(2)> Dim us As UShort<FieldOffset(0)> Dim i As Integer<FieldOffset(0)> Dim ui As UInteger<FieldOffset(0)> Dim fd As SingleEnd StructureStructure MyStructDim b0 As ByteDim b1 As ByteDim b2 As ByteDim b3 As ByteDim s As ShortDim us As UShortDim i As IntegerDim ui As UIntegerEnd StructurePrivate Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.ClickDim mu As MyUnion' 一种安全的int与uint转换方法'mu.ui = UInteger.MaxValuemu.i = &H8234567Fmu.ui = &H7234567FMsgBox(mu.i) ' 一个存储与读取IP数据的方法mu.b0 = 128 : mu.b1 = 0 : mu.b2 = 0 : mu.b3 = 1 '127.0.0.1Dim ip As New Net.IPAddress({128, 0, 0, 1})MsgBox(CInt(ip.GetHashCode) = mu.i) 'ip数值相等' 其他用法...mu.ui = UInteger.MaxValueMsgBox(mu.s) '-1MsgBox(mu.us) '65535End SubEnd Class
下位机和上位机浮点传输示例
如果下位机和上位机是通过串口传输
下位机示例
union DoubleToBit
{unsigned char char_buffer[8];double double_num;
};union FloatToBit
{unsigned char char_buffer[4];float float_num;
};void transFloat(float f_ptr)
{int i;unsigned char data;Float_char_union.float_num = f_ptr;for(i = 0 ; i < 4 ; i++){data = Float_char_union.char_buffer[3-i];write_queue_tx(data);}}void transDouble(double d_ptr)
{int i;unsigned char data;Double_char_union.double_num = d_ptr;for(i = 0 ; i < 8 ; i++){data = Double_char_union.char_buffer[7-i];write_queue_tx(data);}}
上位机示例
Imports System.Runtime.InteropServices '引入运行时非托管数据管理服务Public Class Form1<StructLayout(LayoutKind.Explicit)> _Structure MyUnion<FieldOffset(0)> Dim b0 As Byte<FieldOffset(1)> Dim b1 As Byte<FieldOffset(2)> Dim b2 As Byte<FieldOffset(3)> Dim b3 As Byte<FieldOffset(0)> Dim fd As SingleEnd StructureDim mu As MyUnionmu.b0 = hex1 mu.b1 = hex2 mu.b2 = hex3 mu.b3 = hex4 MsgBox(mu.fd)