QIDI_RF.dll是用C写的,现有一个函数int WriteCard(char KeyType,char *Key;int BlockNo,char * Gut)
我在VB中这样定义的,应该没有错吧
Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Long, ByVal key As String, ByVal block_no As Long, ByRef CardGut As String) As Long
这是一个REID读卡器的,现在的问题是CardGut传进去的数据与拿出来的不一制,QIDI_RF.dll本身没有问题,在delphi中使用正常,CardGut 是一个十六进制的字符串,例如“1234567890ABCDEF”,有人知道这是什么问题吗?

解决方案 »

  1.   

    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal key As String, ByVal block_no As Long, ByVal CardGut As String) As Long
      

  2.   

    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal key As String, ByVal block_no As Long, ByVal CardGut As String) As Long
    是不行的,CardGut 是指针型的CardGut 是通过地址去内存拿数据,是不是VB与C数据在内存中存储或提取的方式不一样?
      

  3.   

    VB字符串与C字符串确实不一样,你在网上搜一下它们转换的方法吧
      

  4.   

    我在网上找到这个:
    Private   Declare   Sub   CopyMemory   Lib   "kernel32"   Alias   _   
                      "RtlMoveMemory"   (hpvDest   As   Any,   ByVal   hpvSource   As   _   
                      Long,   ByVal   cbCopy   As   Long)   
        
      Private   Function   BSTRtoLPSTR(sBSTR   As   String,   b()   As   Byte,   lpsz   As   Long)   As   Long   
        
      '   Input:   a   nonempty   BSTR   string   
      '   Input:   **undimensioned**   byte   array   b()   
      '   Output:   Fills   byte   array   b()   with   ANSI   char   string   
      '   Output:   Fills   lpsz   with   a   pointer   to   b()   array   
      '   Returns   byte   count,   not   including   terminating   null   
      '   Original   BSTR   is   not   affected   
        
      Dim   cBytes   As   Long   
      Dim   sABSTR   As   String   
        
      cBytes   =   LenB(sBSTR)   
        
      '   ReDim   array,   with   space   for   terminating   null   
      ReDim   b(1   To   cBytes   +   2)   As   Byte   
        
      '   Convert   to   ANSI   
      sABSTR   =   StrConv(sBSTR,   vbFromUnicode)   
        
      '   Point   to   BSTR   char   array   
      lpsz   =   StrPtr(sABSTR)   
        
      '   Copy   the   array   
      CopyMemory   b(1),   ByVal   lpsz,   cBytes   +   2   
        
      '   Point   lpsz   to   new   array   
      lpsz   =   VarPtr(b(1))   
        
      '   Return   byte   count   
      BSTRtoLPSTR   =   cBytes   
        
      End   Function   但还是不行,有没有人帮我改一下,能适合十六进制数据
      

  5.   

    QIDI_RF.dll是用C写的,现有一个函数int WriteCard(char KeyType,char *Key;int BlockNo,char * Gut)Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal keyPtr As Long, ByVal BlockNo As Long, ByVal CardGut As Long) As Long如果读卡器用的是ASCII码,用如下方法
    Dim KeyType As Byte
    Dim Key() As Byte
    Dim BlockId As Long
    Dim Data() As Byte
    Key = StrConv("MyKey", vbFromUnicode)
    ReDim Preserve Key(UBound(Key) + 1)
    Data = StrConv("1234567890ABCDEF", vbFromUnicode)
    ReDim Preserve Data(UBound(Data) + 1)
    WriteCard KeyType, VarPtr(Key(0)), BlockId, VarPtr(Data(0))
      

  6.   

    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal key As String, ByVal block_no As Long, ByVal CardGut As String) As Long
    是不行的,CardGut 是指针型的CardGut 是通过地址去内存拿数据,是不是VB与C数据在内存中存储或提取的方式不一样?=============================================就是指针型的才要在vb里面声明成ByVal CardGut As String
    因为vb里面的string是bstr,本质生类似一个指向指针的指针
    你不能拿到数据的原因我估计是你最后一个参数使用不正确,你调用api的时候应该这样:dim bufferStr as String*256 '256只是一个例子,表示缓冲区的大小
    bufferStr=Space(256)然后把bufferStr传进CardGut 里面看看结果如何或者你也可以像楼上那样用Byte数组实现
      

  7.   

    你试试这个声明
    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByRef key As String, ByVal block_no As Long, ByRef CardGut As String) As Long
      

  8.   

    解决了,声明还是用
    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Long, ByVal key As String, ByVal block_no As Long, ByRef CardGut As String) As Long
    如果用
    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal key As String, ByVal block_no As Long, ByVal CardGut As String) As Long
    会提示出错
    在使用时用 ret=WriteCard(KeyType , key , block_no, ByVal CardGut)就可以了
    不过我对使用时加ByVal的原因不是很明白
      

  9.   

    byval是值传递,在vb中的string实际上是一个指针变量,这个指针的内容是字符串的第一个字节的地址。如果用byval,那么传递给函数的实际上是字符串第一个字节的地址,而不是string这个变量的指针。那么被调函数在使用(*p)也就是字符串的前4个字节所指向的内存的时候,由于这块内存是非法的,因此会出现错误。
    byref是地址传递,也就是指针传递,会把string这个变量的地址传递给函数,在vb中也可以表示为VarPtr(string),C语言中是&string,如果用VarPtr(string),就可以用byval了。在这种情况下,被调函数使用*p是没有问题的。
      

  10.   

    在使用的时候加上byval或者byref可以不管声明的是什么,都按照调用时的方式传递。
      

  11.   

    如果byval传递的是字符串(*p)是字符串的第一个字符的值。
    如果用
    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal key As String, ByVal block_no As Long, ByVal CardGut As String) As Long
    会提示出错
    这个应该不会出错,因为楼主调用的时候加上了Byval是正确的
      

  12.   

    int WriteCard(char KeyType,char *Key,int BlockNo,char * Gut)如果 CardGut 是可打印字符:
    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal key As String, ByVal block_no As Long, ByVal CardGut As String) As Long
    提示什么错误,是否你的变量类型不匹配?否则:
    Public Declare Function WriteCard Lib "QIDI_RF.dll" (ByVal KeyType As Byte, ByVal key As String, ByVal block_no As Long, ByRef CardGut As Byte) As Longret = WriteCard(KeyType, strKey, lngBlock, CardGut(0))在 VB 中,String 类型本身是一个指针结构,其指针指向字符串缓冲区。如果 ByRef strX As String, 则传送的是另一个指针,指向 String 的指针。
      

  13.   

    是啊,提示什么错误了?
    ByRef strX As String 传递进去的是一个指向string的指针,而不是指向缓冲区的指针
      

  14.   

    ---------------------------
    vb6.exe - 应用程序错误
    ---------------------------
    "0x04051b66" 指令引用的 "0x3134302f" 内存。该内存不能为 "written"。
    要终止程序,请单击“确定”。
    要调试程序,请单击“取消”。
    ---------------------------
    确定   取消   
    ---------------------------
      

  15.   

    还有,就是读块的时候,我用for读块的时候,一般读到二十几或三十几块的时候也会出现这个错误,不知道是什么原因
      

  16.   

    Public Declare Function ReadCard Lib "QIDI_RF.dll" (ByVal KeyType As Long, ByVal key As String, ByVal block_no As Long, ByRef CardGut As String) As Long
      

  17.   

    Public Declare Function ReadCard Lib "QIDI_RF.dll" (ByVal KeyType As Long, ByVal key As String, ByVal block_no As Long, ByRef CardGut As String) As Long//你这最后一个参数不对吧....如果是要用它返回一个字符串,应该用BYVAL,然后在DLL内对这个指针指向的地址写数据另外,应该还要一个参数指定一下你这个字符串缓冲区的长度,不然你这缓冲区不够长时,小心写挂你的主程序:)
      

  18.   

    VirtualDesktop(^_^) ( ) 信誉:104    Blog   加为好友  2007-5-29 17:37:39  得分: 0  就是指针型的才要在vb里面声明成ByVal CardGut As String
    因为vb里面的string是bstr,本质生类似一个指向指针的指针
    你不能拿到数据的原因我估计是你最后一个参数使用不正确,你调用api的时候应该这样:dim bufferStr as String*256 '256只是一个例子,表示缓冲区的大小
    bufferStr=Space(256)然后把bufferStr传进CardGut 里面看看结果如何或者你也可以像楼上那样用Byte数组实现//晕,原来这里有说.....
      

  19.   

    写用byval现在没问题了,到是读时还有些问题,为什么连续读会有问题呢?
      

  20.   

    看看是不是在读的过程中,有超过缓冲区长度的数据?系统的API的话,对于缓冲区不够长,是作了处理的,返回值里会返回要求的长度(比如GetClassName)不知道你这个API有没有这样的处理或者直接就没作判断,拿来指针就写?那如果偶尔有缓冲区长度以上的数据,我估计是必挂....