如题。
该指针是某 API 的回调函数中的参数,按照参数注释,说明该参数表示的是一个字符串的指针,但没有提供其长度,只知道是(Points to the zero terminated),请问如何获取其实际的字符串内容啊???要是知道长度那简单了,CopyMemory 即可。现在不知道长度,我查了些资料,知道些诸如 lstrcpy、lstrlen、lstrcat 等字符串操作的 API,但是不知道实际该怎么写我尝试写几个都引起崩溃^-^谢谢前辈帮忙!!!

解决方案 »

  1.   

    两个方案:一,使用copymoney(我也想)一个字节一个字节地复制+判断是否为0;二,先将指针所指内存块以一定值(如64字节)为基础设置权限至少为可读,再复制一块判断一块.出于简单.....我给你个第一种思路的代码:dim I as long,Buff() as byte,BuffByte as bytedo
        call copymemory(byval barptr(buffbyte),byval sptr,1)  '复制1字节
        if buffbyte<>0 then         '判断是不是为零
            redim preserve buff(i)
            buff(I)=buffbyte
            i=i+1
        else                         '0就是NULL嘛!结尾了,跳出.
            exit do
        endif
    loopmsgbox strconv(buff(),vbunicode)sptr是你得到的那个指针.这个代码有个条件,就是一定要确认sptr所指向的内存至少有一个允许读取的字节,不然一读就非法操作...XXXXX内存不可读......反正祝你好运吧....= =!
      

  2.   

    call copymemory(byval barptr(buffbyte),byval sptr,1)  '复制1字节这里打错一个字母:call copymemory(byval varptr(buffbyte),byval sptr,1)  '复制1字节
      

  3.   

    可用255以内的字串试一下,一般API的字串参数长度不大于255
      

  4.   

    Public Function CStringPointerToVbString(ByVal lpString As Long) As String
        Dim b() As Byte
        Dim i As Long
        Dim sVal As String
        Dim tmplng As Long
        'check for null pointer
        If lpString = 0 Then Exit Function
        sVal = ""
        i = 0
        Do
            ReDim Preserve b(i)
            'copy string 1 byte at a time until we get null terminator
            CopyMemory b(i), ByVal lpString, BYTE_SIZE
            If b(i) = 0 Then Exit Do
            'sVal = sVal & Chr(b(i))
            lpString = lpString + BYTE_SIZE
            i = i + 1
        Loop
        
    '    ReDim b(0 To (lCurLen - 1))
    '    'copy string to byte array
    '    CopyMemory b(0), ByVal lRowData, BYTE_SIZE * lCurLen
        
        ReDim Preserve b(0 To UBound(b) - 1)
        sVal = StrConv(b(), vbUnicode)
        
        'return the string
        CStringPointerToVbString = sVal
    End Function
      

  5.   

    看来大家都是以 CopyMemory 来一个个的取。。说实话这办法不是那么好莫非没有可以一次性取出来的方法吗???要是真没有,也只有用这个办法了。。1、2楼老马的程序应该是在帖子中自己写的没具体测试吧,有个别小错误的地方(比如指针必须++才可以哦),当然思路和原理是写出来了。
    根据4楼的代码,我自己写了个如下:Private Function GetPtrStr(Pointer As Long) As String
        Dim Buff() As Byte, I As Long
        If Pointer Then
            ReDim Buff(0 To 2 ^ 16) '这里在循环外先定义一个足够大的BUFF是为了避免在循环内每次使用 ReDim 造成效率降低...
            For I = 0 To 2 ^ 16 '使用 FOR 就不用每次 I++了
                CopyMemory Buff(I), ByVal Pointer, 1
                If Buff(I) = 0 Then
                    ReDim Preserve Buff(0 To I - 1) '这个 ReDim 仅发生一次,去掉尾部多余部分
                    Exit For
                End If
                Pointer = Pointer + 1 '指针++
            Next I
            GetPtrStr = StrConv(Buff(), vbUnicode)
        End If
    End Function避免了每次 ReDim ,这个应该在取较大字符串时比4楼的效率一点点吧...但是我还是想知道是否真的没有一次性取出来的方法???比如用其他的函数...
        象 lstrlen,咱们一般都是直接用字符串来做参数,但是按照MSDN定义,其实该参数应该就是字符串指针,所以如果可以直接提供指针参数,这个函数不可以一次性取出 零结尾的字符串 的长度吗???
        另外见到本站说起过一个函数 MapViewOfFile 或者 MapViewOfFileEx,但是不会用,原帖子在:
    http://topic.csdn.net/t/20021012/14/1090430.html
      

  6.   

    哈哈,成功了,我按照楼上自己的思路尝试又写了2个..貌似可以...大家看看可否有需要修改之出:
    Private Declare Function lstrlenW Lib "kernel32.dll" (ByVal lpszString As Long) As Long
    Private Declare Function lstrcpyW Lib "kernel32.dll" (lpszString1 As Any, lpszString2 As Any) As LongPrivate Function GetPtrStr2(Pointer As Long) As String
        Dim Buff() As Byte, I As Long
        If Pointer Then
            I = lstrlenW(Pointer) * 2
            ReDim Buff(0 To I - 1)
            CopyMemory Buff(0), ByVal Pointer, I
            GetPtrStr2 = StrConv(Buff(), vbUnicode)
        End If
    End FunctionPrivate Function GetPtrStr3(Pointer As Long) As String
        Dim Buff() As Byte
        If Pointer Then
            ReDim Buff(0 To lstrlenW(Pointer) * 2 - 1)
            lstrcpyW Buff(0), ByVal Pointer
            GetPtrStr3 = StrConv(Buff(), vbUnicode)
        End If
    End Function