WinCE下VB.NET程序的开发

简介: 最近朋友的一个项目有这样的需求,让我帮忙探个路。经过两天的努力,总算是有点收获。       VB.NET是一种面向对象的计算机编程语言,可以看做是Visual Basic的升级版。它也是Visual Studio.NET的核心语言之一。

      最近朋友的一个项目有这样的需求,让我帮忙探个路。经过两天的努力,总算是有点收获。

      VB.NET是一种面向对象的计算机编程语言,可以看做是Visual Basic的升级版。它也是Visual Studio.NET的核心语言之一。开发人员可以利用它快速而高效的创建出基于.NET Framework的应用程序。.NET Framework家族也包括了面向移动设备领域的两个成员,它们分别是.NET Compact Framework和.NET Micro Framework。其中.NET CF可以认为是WinCE平台上.NET Framework的精简版,而.NET MF则面向更小型的设备。

     要让WinCE支持VB.NET,需要在定制系统时添加.NET Compact Framework组件。这很简单,在PB5.0或6.0中将相应的组件选入到Catalog中,重新编译系统即可。主要问题是如何编写一个应用程序,并且能访问底层硬件的数据。

     翻箱倒柜,找出很久以前买的一本VB.NET的书,快速地翻看了几个重要的章节,对VB.NET有了大概的了解,并基本确定了实现方式——使用动态链接库(DLL)。

     实现过程中,最大的麻烦就是语言不熟悉。传说中的“拖拉拽”快速编程方式在我这变成了拖拉机。好在之前先用C实现了功能,参照着改到VB下来,要容易不少。下面就VB的代码部分做一个简单的总结,以备后用。

     首先是自定义常量,效果等同于宏定义。

    Const WRITE_BASE_ADDRESS = &H0           ' 用于写入数据的基地址
    Const READ_BASE_ADDRESS = &H1000         ' 用于读取数据的基地址

     VB.NET中的结构体定义格式如下。

Private Structure CMDINFO
      Dim pCMDBuf As UInteger         ' 指令缓冲区,应用申请空间,指针类型
       Dim dwWriteAddr As UInteger     ' 指令写入的地址
       Dim dwCMDLen As UInteger        ' 指令的长度
       Dim dwRetryCount As UInteger    ' 重试的次数
       Dim dwDelayTime As UInteger     ' 重试的周期,以ms为单位
End Structure
Private Structure READINFO
      Dim pReadBuf As UInteger         ' 读取数据的缓冲区,库申请空间,指针类型
      Dim dwDataAddr As UInteger       ' 读取RAM的地址
      Dim dwReadLen As UInteger        ' 读取数据的长度
      Dim dwRetryCount As UInteger     ' 重试的次数
      Dim dwDelayTime As UInteger      ' 重试的周期
  End Structure

    DLL中实现的库函数的声明。

    Private Declare Function SendCommand Lib "DPRAMLib" (ByVal CMDInfo As CMDINFO) As Integer
    Private Declare Function ReadDPRAM Lib "DPRAMLib" (ByRef ReadInfo As READINFO) As Integer
    Private Declare Sub WritePort Lib "DPRAMLib" (ByVal Port As UShort, ByVal Value As Byte)
    Private Declare Function ReadPort Lib "DPRAMLib" (ByVal Port As UShort) As Byte

     需要注意的是,如果函数有返回值须使用Function,如果没有返回值,则使用Sub,否则,程序在运行过程中会出现异常。如果函数的参数为指针或者引用类型,则用ByRef,如果是值传递,则用ByVal。

Private Sub ButtonRead_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonRead.Click
        Dim i As Integer
        Dim szTmp As String
        Dim szShowBuf As String
        Dim ReadBuf As Byte()
        ' 获取地址
        RamAddr = Val("&H" + TextBoxAddr.Text.Substring(2))
        ' 获取长度
        Length = Val("&H" + TextBoxLength.Text.Substring(2))
        ' 调用库函数读取RAM
        stReadInfo.dwDelayTime = 2
        stReadInfo.dwRetryCount = 5
        stReadInfo.dwDataAddr = RamAddr     
        stReadInfo.dwReadLen = Length       
        stReadInfo.pReadBuf = vbNullString  
        ReadDPRAM(stReadInfo)
 
        Length = stReadInfo.dwReadLen - 1 ' 将长度转换为索引的最大值
        ' 获取读取出来的数据长度,并分配相应的内存
        ReDim ReadBuf(Length)
        ' 将库中读取的数据拷贝至托管代码的数组中,以便处理
        Marshal.Copy(stReadInfo.pReadBuf, ReadBuf, 0, stReadInfo.dwReadLen)
        ' 显示读取到的内容
        szShowBuf = "0000:"
        For i = 0 To Length Step 1
            szTmp = Hex(ReadBuf(i))
            If szTmp.Length = 1 Then
                szTmp = "0" & szTmp
            End If
            szShowBuf = szShowBuf & szTmp & " "
            If (i + 1) Mod (8) = 0 Then
                szShowBuf = szShowBuf & vbCrLf ' 加入换行符
                If i < Length Then
                    szTmp = Hex(i + 1)
                    Dim szTmp2 As New String("0", 4 - Len(szTmp))
                    szTmp = szTmp2 & szTmp & ":"
                    szShowBuf = szShowBuf & szTmp
                End If
            End If
        Next
        TextBoxValue.Text = szShowBuf
    End Sub

     以上代码调用库函数读取数据,并在EDIT控件中以十六进制的方式显示出来。其中,用Val和Hex做字符串和十六进制数据之间的转换。Marshal用来处理托管代码和非托管代码之间的数据封送。

Private Sub ButtonWrite_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles ButtonWrite.Click
        Dim i As Integer, j As Integer, nLength As Integer
        Dim nValue As Byte
        Dim szTmp As String
        Dim WriteBuf As Byte()
        
        RamAddr = Val("&H" + TextBoxAddr.Text.Substring(2))
 
        ' 获取需要写入的数据
         nLength = TextBoxValue.Text.Length()
        ReDim WriteBuf((nLength + 1) / 3)
        i = 0
        j = 0
        While i < nLength
            szTmp = "&H" + Mid(TextBoxValue.Text, i + 1, 2)
            nValue = Val(szTmp)
            WriteBuf(j) = nValue
            i += 3
            j += 1
        End While
        Dim pt As New IntPtr
        pt = Marshal.AllocHGlobal(j)        ' 从进程的非托管内存中分配内存
         Marshal.Copy(WriteBuf, 0, pt, j)    ' 将数据从托管数组复制到非托管内存指针
        ' 调用库函数写入RAM
        stCmdInfo.pCMDBuf = pt
        stCmdInfo.dwCMDLen = j
        stCmdInfo.dwDelayTime = 2
        stCmdInfo.dwRetryCount = 5
        stCmdInfo.dwWriteAddr = RamAddr
        SendCommand(stCmdInfo)
        Marshal.FreeHGlobal(pt)   ' 释放使用AllocHGlobal 从进程的非托管内存中分配的内存
    End Sub

     以上代码调用库函数,将用户输入的十六进制数据写入到RAM中。

目录
相关文章
|
1月前
|
SQL 开发框架 数据可视化
企业应用开发中.NET EF常用哪种模式?
企业应用开发中.NET EF常用哪种模式?
|
2月前
|
开发框架 JavaScript 前端开发
5个.NET开源且强大的快速开发框架(帮助你提高生产效率)
5个.NET开源且强大的快速开发框架(帮助你提高生产效率)
|
3月前
|
域名解析 缓存 Linux
如何让你的.NET WebAPI程序支持HTTP3?
如何让你的.NET WebAPI程序支持HTTP3?
47 2
如何让你的.NET WebAPI程序支持HTTP3?
|
4月前
|
SQL 开发框架 数据可视化
企业应用开发中.NET EF常用哪种模式?
企业应用开发中.NET EF常用哪种模式?
|
4月前
|
开发框架 缓存 Cloud Native
微软发布 .NET 云原生开发框架—— .NET Aspire
微软于 2023-11-14日 发布了 .NET 8 的正式版。伴随着这个重要 .NET 版本的发布,微软也发布了一个全新的 .NET云原生开发框架 —— .NET Aspire,它提供了如下 3 个方面的能力,来帮助我们使用 .NET 开发分层、云就绪的可观测、本地与生产环境一致的分布式云原生应用程序。
197 0
|
4天前
|
开发框架 前端开发 JavaScript
采用C#.Net +JavaScript 开发的云LIS系统源码 二级医院应用案例有演示
技术架构:Asp.NET CORE 3.1 MVC + SQLserver + Redis等 开发语言:C# 6.0、JavaScript 前端框架:JQuery、EasyUI、Bootstrap 后端框架:MVC、SQLSugar等 数 据 库:SQLserver 2012
|
30天前
|
数据安全/隐私保护 Windows
.net三层架构开发步骤
.net三层架构开发步骤
11 0
|
30天前
深入.net平台的分层开发
深入.net平台的分层开发
48 0
|
2月前
|
开发框架 前端开发 .NET
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
为了便于大家查找,特将之前开发的.Net Core相关的五大案例整理成文,共计440页,32w字,免费提供给大家,文章底部有PDF下载链接。
32 1
福利来袭,.NET Core开发5大案例,30w字PDF文档大放送!!!
|
3月前
|
C#
.NET开发中合理使用对象映射库,简化和提高工作效率
.NET开发中合理使用对象映射库,简化和提高工作效率