dll 中 回调 vb 当中的函数
在工程中能正常运行
编译成EXE文件以后,只要回调函数一工作程序就自动退出不显示任何错误(如果回调函数内无任何语句
则程序正常)
请各位高手看一下这个回调函数里面语句是否有问题? 
Public Sub myfunction(ByVal ltype As Long, ByVal msg As Long, ByVal pprarm As Long, ByVal NID As Long)
Dim txtmsg(1 To 200) As Byte
Dim mrc As ADODB.Recordset
Dim txtSQL As String
Dim MsgText As String
Dim ErrNum As LongCopyMemory ByVal VarPtr(txtmsg(1)), ByVal msg, 200
reterr = ByteArray2String(txtmsg, 200)   '将字节转化为字符串If Trim(reterr) = "OK" And ltype= 100 Then
        txtSQL = "dll_succed " + Str(NID)
        Set mrc = ExecuteSQL(txtSQL, MsgText, ErrNum)  '执行一个SQL的存储过程
End If
End Sub
Public Function ByteArray2String(BIN() As Byte, BINLen As Integer) As String
    On Error Resume Next
    
    Dim N As Integer
    Dim strReturn As String
   
    
    strReturn = ""
    For N = 1 To BINLen
        If BIN(N) = 0 Then Exit For
        
        strReturn = strReturn & Chr(BIN(N))
      
    Next
    ByteArray2String = strReturn
    
End Function

解决方案 »

  1.   

    经过调试,Dim txtmsg(1 To 200) As Byte 这条语句有就退出,不知何故?
      

  2.   

    你的ExecuteSQL会出错吗?这样看很难看出来的
      

  3.   

    不会吧,怎么 会是Dim txtmsg(1 To 200) As Byte 的错误呢我估计应该是CopyMemory 内存的问题,
    试改为
    CopyMemory ByVal (txtmsg(1)), ByVal msg, 200看看
      

  4.   

    或者
    CopyMemory txtmsg(1), ByVal varptr(msg), 200看看
      

  5.   

    应该是CopyMemory的问题//CopyMemory ByVal VarPtr(txtmsg(1)), ByVal msg, 200
    你的msg的确切含义是什么建议你把程序去掉无关的代码后完整的贴出来
      

  6.   

    这是回调函数的定义及说明:
    (VC调用)typedef void (__stdcall * CALLBACKFUNCTION) (unsigned long ltype, const void *plParam, void *prParam, int nID);
    1.函数的第一个参数为命令类型,是一个长整形。
    2.函数的第二个参数为调用结果,是一个字符指针,结果有二种:OK ,ERROR
    3.函数的第三个为你登记回调函数时传进去的指针。
    登记回调函数的原型为:typedef void (__stdcall * _REGISTCALLBACKFUNCTION) (_CALLBACK addres, void *);
    4.函数的第四个为命令ID,是在主程序中调用DLL中的ComputerTTL时的返回值。
    我在主程序中的一个FORM1中的程序为:
    Private Sub Form_Load()
    Call RegistCallbackFunction(AddressOf myfunction, 0)
    End Sub
    Private Function count(str as string) As Boolean
    dim ret as long
       ret = ComputerTTL()  调用DLL中的函数ComputerTTL,从而引起回调函数
    End Function请大家注意:这些程序在VB的IDE环境中执行完全正确,但编译成EXE文件后,只要回调函数工作程序就无错误退出.
      

  7.   

    //请大家注意:这些程序在VB的IDE环境中执行完全正确,但编译成EXE文件后,只要回调函数工作程序就无错误退出.编译成p-代码试试
      

  8.   

    非常感谢LGYAN,但我的回调函数是需要硬件配合的所以无法将程序发给你
    经过测试,dim txtmsg(1 to 200) as byte
    这条语句只要加上,程序就退出,注解掉就没问题
    但这样一来字符串指针中的字符就无法获取了,不知到有没有其他
    从VC的DLL中获取字符的VB实现语句
      

  9.   

    对了,我可以知道问题了。是CopyMemory ByVal VarPtr(txtmsg(1)), ByVal msg, 200的问题
    可能是内存出错,你Copy了不该Copy的东东,也就是说你可能无法从msg地址中Copy出200个字节的数据!!!
      

  10.   

    呵呵,根据你的回调函数原形
    typedef void (__stdcall * CALLBACKFUNCTION) (unsigned long ltype, const void *plParam, void *prParam, int nID);
    换成vb应该是这样的吧
    Public Sub myfunction(ByVal ltype As Long, msg As Long, pprarm As Long, ByVal NID As Long)
      

  11.   

    我在调试时,将myfunction()中所有语句均注解掉,只剩下以下内容
    Dim txtmsg(1 To 200) As Byte
    Dim mrc As ADODB.Recordset
    Dim txtSQL As String
    Dim MsgText As String
    Dim ErrNum As Long
    此时编译成EXE文件,运行则退出,
    如果再注解掉Dim txtmsg(1 To 200) As Byte,则程序无问题
    所以我由此断定是否回调函数中不能有次类定义:Dim txtmsg(1 To 200) As Byte
      

  12.   

    上面的回调函数声明我已经试过,如此声明连VB的IDE环境中都出现读取不能够读写的内存错误,我在调试时,将myfunction()中所有语句均注解掉,只剩下以下内容
    Dim txtmsg(1 To 200) As Byte
    Dim mrc As ADODB.Recordset
    Dim txtSQL As String
    Dim MsgText As String
    Dim ErrNum As Long
    此时编译成EXE文件,运行则退出,此时出现的错误信息为:
    “0x6601d640"指令引用"0x00000076"内存,该内存不能为”read“
    如果再注解掉Dim txtmsg(1 To 200) As Byte,则程序无问题
      

  13.   

    //是CopyMemory ByVal VarPtr(txtmsg(1)), ByVal msg, 200的问题
    //可能是内存出错,你Copy了不该Copy的东东,也就是说你可能无法从msg地址中Copy出200
    //个字节的数据!!!我只COPY两个字节也照样错误:
    “0x6601d640"指令引用"0x00000076"内存,该内存不能为”read“
    并且这个错误还是由Dim txtmsg(1 To 200) As Byte引起的
    这是我通过一条一条语句注解然后编译运行的方法定位出来的
      

  14.   

    奇怪的问题,你有dll的源码吗?有的话,贴出来
      

  15.   

    由于没有DLL的源码,我想大家能否想一个办法不用我程序中API函数的CopyMemory和
    DIM txtmsg(1 to 200) as byte语句
    只要将声明中typedef void (__stdcall * CALLBACKFUNCTION) (unsigned long ltype, const void *plParam, void *prParam, int nID);
    const void *plParam 这个指针所指向的字符内容读出即可
      

  16.   

    在我的回调函数myfunction中
    Public Sub myfunction(ByVal ltype As Long, ByVal msg As Long, ByVal pprarm As Long, ByVal NID As Long)msg的数值就是const void *plParam 这个指针
      

  17.   

    改成:
    CopyMemory ByVal VarPtr(txtmsg(1)), msg, 200
    试试
    参考:http://dev.csdn.net/article/12/12675.shtm
    希望对你有帮助