各位论坛里的同行:
   最近遇到一个让我崩溃的问题,给客户做了一个程序,需要跟门锁做接口,门锁方提供了一个用c++写的函数,我在使用vb调用的过程中遇到了一个让俺崩溃的问题,希望高手来答疑解惑,我不胜感激!

解决方案 »

  1.   

    我把函数的原型和我在vb里调用的代码贴给大家。
    函数原型(用c++写的):
    __HotelLock__ int __stdcall write_card(unsigned char Card,unsigned char *CardType,unsigned char *Buffer);
    我在vb里的声明以及调用方法:
    Declare Function write_card Lib "HLApi.dll" (ByVal card As Integer, ByVal cardtype As String, ByVal buffer As String) As Integer
    调用方法              Dim cardtype As string *2
                dim card as integer
                Dim buffkx As String * 55
                buffkx = "1A571EFF01020508090313000809041200123456"
                cardtype = "23"
                card = 7
                Rvalue = write_card(card, cardtype, buffkx)
    执行 write_card的时候报内存错误!请诸位高手指点一下,共同学习。
      

  2.   

    楼上的首先谢谢您的回复,应该是声明的类型出现了问题,现在就是想问下c++ 里的unsigned char * 在vb中对应的变量类型!
    2楼的,生死有命,富贵在天。要死的时候是谁都拦不住的,或许你应该相信科学,去医院看看把!
      

  3.   

    那时指针吗?是不是要个数组啊!不知道行不行
    Declare Function write_card Lib "HLApi.dll" (ByVal card As Integer, ByVal cardtype() As String, ByVal buffer() As String) As Integer 
      

  4.   

    C   DLL   原型                          VB声明                                   
          
      int   a                       ByVal   a   as   long                  
      long   a                      ByRef   a   as   long                  
      int   *pa                     ByRef   pa   as   long               
      long   *pa                    ByVal   pa   as   long                  
      char   *pstr                  ByVal   pstr   as   string                      
      wchar   *pstr                 ByRef   pstr   as   string          
      struct   tagX   *p            ByRef   p   as   tagX                                    
      HANDLE   h                    ByVal   h   as   long                       
      

  5.   

    unsigned char *CardType
    对应变体变量
      

  6.   

    谢谢楼上两位的回复,7楼兄弟的  char *pstr  byval pstr as string 肯定是不对的。8楼兄的建议我正在测试,看看有效果否,可能我就是没有试验定义为变体变量了。总有漏网之鱼 (*^__^*) 嘻嘻……!
      

  7.   

    Declare Function write_card Lib "HLApi.dll" (ByVal card As byte, ByVal cardtype As long, ByVal buffer As long) As longDim cardtype() As byte
    dim card as byte
    Dim buffkx() As byte buffkx = StrConv("1A571EFF01020508090313000809041200123456", vbFromUnicode)
    redim preserve buffkx(ubound(buffkx)+1)   '最后的一个0 
    cardtype = StrConv("23" ,vbFromUnicode)
    redim preserve cardtype (ubound(cardtype )+1)   '最后的一个0 
    card = 7 Rvalue = write_card(card, varptr(cardtype(0)), varptr(buffkx(0)) 
    这样试下看看另外,内存错误,是某地址不可读,还是不可写?你这个API仅是把这些值写入到卡里,而不需要从参数里返回值吗?
      

  8.   

    内存报错, 该内存不能为"read"的报错提示。还有这个参数仅仅是把内容写到卡里并不返回值!
      

  9.   

    试试这样Declare Function write_card Lib "HLApi.dll" (ByVal card As byte, ByVal cardtype As String, ByVal buffer As String) As Integer  Dim cardtype As String * 256
    dim card as byte
    Dim buffkx As String * 256

    buffkx = "1A571EFF01020508090313000809041200123456"
    cardtype = "23"
    card = 7

    Rvalue = write_card(card, cardtype, buffkx) 
      

  10.   


    既然是内存不可读,那你这样试一下看看:还是使用我的那种代码,不过在调用API前,先MSGBOX "&H" & hex(varptr(cardtype(0))) & "/&H" & hex(varptr(buffkx(0)))打印出这两个地址后,再看看出错时是什么地址不可读,看看是不是超过了上面某个地址加上其内容长度的位置.我在猜想是DLL里面决定字符串参数结尾的方法与VB的不同,所以才造成不断地向某个指针的后面读;由于一直没有读到结束符号,所以读到了不可读的内存,造成错误.另外最好与DLL作者联系一下,毕竟这个问题由他协助解决的话会容易得多,大家也不用猜来猜去,你也不用试来试去
      

  11.   

    老马谢谢您的建议啊,您说的有道理,那个dll作者已经消失了,找不到人,苦闷啊我。!这个参数是带入带出参数既要传入数据还要接收返回数据。
      

  12.   

    晕倒........原来还要作为返回啊之前不是说不需要用作返回么?那这样吧.......把缓冲区定到4096.....redim preserve buffkx(4095)   '最后的一个0并且仍然将第一个元素的地址显示出来,再看看是否会出错,出错的地址又是哪里,记下偏移量,不要点击确定,用冰刃查看一下这几个指针所指的内存到底是怎么回事.另外也可以用OD跟踪一下这个API的执行,看看是哪一步出现的错误,再想对策作者消失.....怎么这样可怜啊.不然,干脆再写个DLL得了.....反正应该也只是对硬件的API的封装吧....
      

  13.   

    老马,多谢啊!呵呵,我正在尝试你最后的建议,这个c++写的dll需要调用人家的硬件,所以我无法自己重新写dll,因为人家不提供对硬件的读取!否则就泄密了!
      

  14.   


    看看会不会是Byval Byref 的问题.
      

  15.   

    ...实在不行你看能不能用C++再封装一下,然后用VB去调新封装的dll。也就是说,在C++里做变量类型转换,转换成vb好用的变量类型。
      

  16.   

    谢谢楼上回复,byval byref 的方式我都尝试了,还是报内存错误的!22楼,我不会c++呵呵,这个就行不通了。
      

  17.   

    哎呀,看你弄了这么半个月了,不如找人把你这DLL给反了算了这DLL里是操作硬件的,那么最终也就是封装了几个API,而这几个API肯定是硬件厂家提供的,不然他生产硬件给谁用去....或者直接找厂家要SDK吧,直接在VB里操作硬件,别用DLL了.....如果你就是专门要用DLL封装一些操作,但又不会VC,看看用我这个工具写写能不能工作:http://www.skycn.com/soft/20814.html