VB内存拷贝方式读取二进制文件(二进制数据转换为16进制字符串)

使用CopyMemory的API函数,内存拷贝。

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal Length As Long)

VB代码Sample如下:

功能描述:VB通过调用C++接口读取二进制文件,按照约定格式按序读取Data,读出的二进制内容转换成字符串(16进制格式字符串);

Option Explicit

 

 

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

'C++接口的定义

'typedef struct {

'    UINT NoID;

'    LPSTR lpData;

'    DWORD dwLen;

'}DNLOADDATA;

'

'typedef BOOL (WINAPI *TESTOPENFILE)(char* inszfilename);

'typedef void (WINAPI *TESTCLOSEFILE)(void);

'typedef BOOL (WINAPI *TESTGETINFOBYINDEX)(DWORD dwIndex,DNLOADDATA *dnloadDATA);

'typedef DWORD (WINAPI *TESTGETTOTALNUM)(void);

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''

 

 

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" _

                                        (Destination As Any, Source As Any, ByVal Length As Long)

 

 

Private Declare Function TESTOpenFile Lib "TEST.dll" (ByVal inszfilename As String) As Boolean

Private Declare Sub TESTCloseFile Lib "TEST.dll" ()

Private Declare Function TESTGetTotalNum Lib "TEST.dll" () As Long

 

'Private Declare Function TESTGetInfoByIndex Lib "TEST.dll" (ByVal dwIndex As Long, ByRef aDNLoadDATA As DNLOADDATA_A) As Boolean

Private Declare Function TESTGetInfoByIndex Lib "TEST.dll" (ByVal dwIndex As Long, ByRef aDNLoadDATA As DNLOADDATA_B) As Boolean

 

 

 

Private Type myDATA

    NoID As String

    DATA As String

End Type

Private m_myDATA() As myDATA

 

Private Type DNLOADDATA_B

    NoID(4 - 1) As Byte

    lpData(1) As Long             '第0位:存放Data地址; 第1位:存放Data长度(301个byte);

    dwLen As Long

End Type

 

'Private Type DNLOADDATA_A

'    NoID As Long                    '只能取到内存地址

'    lpData As String          '不能用string, 遇到ascii 0就自动结束了, 导致数据不全

'    dwLen As Long

'End Type

 

Private Sub FileToArray()

    Dim b As Boolean

    Dim aDNLoadDATA As DNLOADDATA_B

    Dim nIndex As Long

   

    Me.MousePointer = 11

   

    Dim nTotalNum As Long

    nTotalNum = TEST_GetTotalNum()       '调用TESTGetTotalNum接口

   

    Dim aByte1() As Byte

    Dim n As Long

    Dim nNoID As Long

    Dim sNoID As String

    Dim sDATA As String

   

    ReDim m_myDATA(0)

    For n = 0 To nTotalNum - 1

        b = TEST_GetInfoByIndex_B(n, aDNLoadDATA)      '调用TESTGetInfoByIndex接口

 

        If b = False Then

            MsgBox "获取第 " & n & " 个DATA Data出错!", vbCritical

            Exit Sub

        End If

 

        'NoID

        nNoID = aDNLoadDATA.NoID(3) + aDNLoadDATA.NoID(2) * 2 ^ 8 + aDNLoadDATA.NoID(1) * 2 ^ 16 + aDNLoadDATA.NoID(0) * 2 ^ 24     '计算NoID值

        sNoID = Format$(nNoID, "000000000")     '转成固定9位字符串, 不够补零

       

        'Data

        ReDim aByte1(aDNLoadDATA.lpData(1) - 1)                     '重新定义长度(根据data的长度定义), 第1位:存放Data长度(301个byte);

       

        CopyMemory aByte1(0), ByVal aDNLoadDATA.lpData(0), 301      '关键:通过内存拷贝方式把地址中的数据存放到byte数组

 

        'byte转换成string

        If ByteToStr(aByte1, sDATA) = False Then

            MsgBox "bytetostr error"

            Exit Sub

        End If

   

        'Check NoID

        If Len(sNoID) <> 9 Then

            MsgBox "第" & n & "个NoID: " & sNoID & "有错误, 长度不为9."

            Exit Sub

        End If

        If IsNumeric(sNoID) = False Then

            MsgBox "第" & n & "个NoID: " & sNoID & "有错误, 不为有效的数字."

            Exit Sub

        End If

       

        'Check DATA

        If Len(sDATA) <> 602 Then

            MsgBox "第" & n & "个DATA有错误, 长度不为602."

            Exit Sub

        End If

 

        '数据放入数组中

        ReDim Preserve m_myDATA(n + 1)        '增加一个长度

        With m_myDATA(n + 1)

            .NoID = sNoID

            .DATA = sDATA

        End With

    Next n

   

    Me.MousePointer = 0

       

End Sub

 

'byte数组转换为string

Private Function ByteToStr(aByte() As Byte, ByRef sReturnDATA As String) As Boolean

    Dim strTmp As String

    Dim m As Long

   

    strTmp = ""

    For m = 0 To UBound(aByte)

        strTmp = strTmp & IIf(aByte(m) < 16, "0" & Hex$(aByte(m)), Hex$(aByte(m))) '& Space(1)

    Next m

 

    sReturnDATA = strTmp

   

    ByteToStr = True

End Function

 

'string转换为byte数组

Private Function StrToByte(ByVal sDATA As String, ByRef aByte() As Byte) As Boolean

    Dim n As Long, i As Long

    n = Len(sDATA) / 2

    If n <= 0 Then

        Exit Function

    End If

   

    ReDim aByte(n - 1)

    For i = 0 To n - 1

        aByte(i) = Val("&H" & Mid$(sDATA, i * 2 + 1, 2))

    Next i

   

    StrToByte = True

End Function

 

 

 

'封装C++接口

Public Function TEST_OpenFile(ByVal sFileName As String) As Boolean

    On Error GoTo errDeal

   

    TEST_OpenFile = TESTOpenFile(sFileName)

   

    Exit Function

 

errDeal:

    MsgBox Err.Description

    On Error GoTo 0

End Function

 

'封装C++接口

Public Function TEST_GetTotalNum() As Long

    On Error GoTo errDeal

   

    TEST_GetTotalNum = TESTGetTotalNum()

   

    Exit Function

 

errDeal:

    MsgBox Err.Description

    On Error GoTo 0

End Function

 

'封装C++接口

Public Sub TEST_CloseFile()

    On Error GoTo errDeal

   

    Call TESTCloseFile

   

    Exit Sub

 

errDeal:

    MsgBox Err.Description

    On Error GoTo 0

End Sub

 

'封装C++接口

'Public Function TEST_GetInfoByIndex(ByVal nIndex As Long, ByRef aDNLoadDATA As DNLOADDATA_A) As Boolean

'    On Error GoTo errDeal

'

'    TEST_GetInfoByIndex = TESTGetInfoByIndex(nIndex, aDNLoadDATA)

'

'    Exit Function

'

'errDeal:

'    MsgBox Err.Description

'    On Error GoTo 0

'End Function

 

'封装C++接口

Private Function TEST_GetInfoByIndex_B(ByVal nIndex As Long, ByRef aDNLoadDATA As DNLOADDATA_B) As Boolean

    On Error GoTo errDeal

   

    TEST_GetInfoByIndex_B = TESTGetInfoByIndex(nIndex, aDNLoadDATA)

   

    Exit Function

 

errDeal:

    MsgBox Err.Description

    On Error GoTo 0

End Function

 

 

转载于:https://www.cnblogs.com/mwming/archive/2013/03/21/2972935.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值