Private Declare Sub CopyMemory Lib "KERNEL32" Alias "RtlMoveMemory" _
(Destination As Any, Source As Any, ByVal Length As Long)
Private Declare Function ArrayPtr Lib "msvbvm60.dll" Alias "VarPtr" (ByRef ary() As Any) As Long
Private Declare Function InitialSendData Lib "SendData.dll" () As Long
Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As String, ByVal iDataBufLen As Long) As LongPrivate Declare Function TerminalSendData Lib "SendData.dll" ()Private Type TRANSMITMESSAGEHEAD
        datatype As Integer
        treatflag As Integer
        date As Long
        record As Long
        dbid(4) As Byte
        serverno As Byte
        iSourceFileNum As Integer
End TypePrivate Type SOURCE_HEAD
        suffix(3) As Byte
        Length As Long
End Type
Private Headstructure As TRANSMITMESSAGEHEAD
Private HeadSource As SOURCE_HEAD
Private Sub Command1_Click()
Dim i As Long
Dim state As Long
Dim state1 As Long
Dim Ttext As String
Dim Ztext As String
Dim sDataBuf() As Byte
Dim sDataBuf0() As Byte
Dim sDataBuf1() As Byte
Dim sDataBuf2() As Byte
Dim sDataBuf3(0 To 8) As Byte
Dim sDataBuf4() As Byte
Dim sDataBuf5() As Byte
state = InitialSendData
Headstructure.datatype = 111
Headstructure.treatflag = 0
Headstructure.iSourceFileNum = 1
ReDim sDataBuf1(Len(Headstructure))
CopyMemory sDataBuf1(0), Headstructure, Len(Headstructure)
sDataBuf2 = sDataBuf1
PackBytes HeadSource.suffix, "txt"
HeadSource.Length = 10
ReDim sDataBuf1(Len(HeadSource) + Len(Headstructure))
CopyMemory sDataBuf1(Len(Headstructure)), HeadSource, Len(HeadSource)
For i = Len(Headstructure) To (Len(HeadSource) + Len(Headstructure))
sDataBuf3(i - Len(Headstructure)) = sDataBuf1(i)
Next i
ReDim sDataBuf0(Len(HeadSource) + Len(Headstructure))
For i = 0 To Len(Headstructure)
sDataBuf0(i) = sDataBuf2(i)
Next i
For i = Len(Headstructure) To (Len(HeadSource) + Len(Headstructure))
sDataBuf0(i) = sDataBuf3(i - Len(Headstructure))
Next i
Ttext = "到底行不行"
ReDim sDataBuf4(LenB(Ttext) - 1)
PackBytes sDataBuf4, TtextZtext = "<IRISDATA><TaskNo>地方</TaskNo></IRISDATA>"
ReDim sDataBuf5(LenB(Ztext) - 1)
PackBytes sDataBuf5, Ztext
ReDim sDataBuf(Len(HeadSource) + Len(Headstructure) + LenB(Ttext) + LenB(Ztext))
For i = 0 To (Len(HeadSource) + Len(Headstructure))
sDataBuf(i) = sDataBuf0(i)
Next i
For i = 0 To LenB(Ttext) - 1
sDataBuf(i + Len(HeadSource) + Len(Headstructure)) = sDataBuf4(i)
Next i
For i = 0 To LenB(Ztext) - 1
sDataBuf(i + Len(HeadSource) + Len(Headstructure) + LenB(Ttext)) = sDataBuf5(i)
Next i
state1 = SendData(VarPtr(sDataBuf(0)), 129)End SubPrivate Sub Command2_Click()
Call TerminalSendData
End SubPrivate Sub PackBytes(ByteArray() As Byte, ByVal PostData As String)
        Dim iNewBytes As Long     '数组预设长度
        Dim intAscii As Integer     '一个字符(Unicode)的Asc编码,中文字符时其值小于0
        Dim mCurNo As Integer    '当前操作的Byte数组下标
        Dim CharHex As String    '当前操作字符的十六进制字符串
        mCurNo = 0
        iNewBytes = LenB(PostData) - 1     '字符串长度Len(str)的两倍注意用的是LenB()函数,数组下标从0开始,要减去1
        If iNewBytes < 0 Then
          Exit Sub
        End If
        
        For i = 0 To Len(PostData)
          ch = Mid(PostData, i + 1, 1)    '获取一个字符
          If ch = Space(1) Then '如果是空跳过
                ch = " "
          End If
          If ch <> "" Then
              intAscii = Asc(ch)        '取其Asc码
              If intAscii > 0 Then        '<0则为中文
                  ByteArray(mCurNo) = Asc(ch)    '英文,直接取其Asc码
                  mCurNo = mCurNo + 1    '设置计数器
              Else
                  CharHex = Hex(intAscii)    '中文时先转为十六进制
                  ByteArray(mCurNo) = HEX_to_DEC(Left(CharHex, 2))        '将前两位转换为十进制,注意这里不用Cbyte()类型转换,因为一些非中文字符时会出现错误。
                  ByteArray(mCurNo + 1) = HEX_to_DEC(Right(CharHex, 2))    '将后两位转换为十进制
                  mCurNo = mCurNo + 2    '设置计数器
              End If
          End If
        Next i
        'ReDim Preserve ByteArray(mCurNo - 1) '截掉多余的部分
    End SubPublic Function HEX_to_DEC(ByVal Hex As String) As Long '将十六进制转换为十进制
    Dim i As Long
    Dim B As Long    Hex = UCase(Hex)
    For i = 1 To Len(Hex)
        Select Case Mid(Hex, Len(Hex) - i + 1, 1)
            Case "0": B = B + 16 ^ (i - 1) * 0
            Case "1": B = B + 16 ^ (i - 1) * 1
            Case "2": B = B + 16 ^ (i - 1) * 2
            Case "3": B = B + 16 ^ (i - 1) * 3
            Case "4": B = B + 16 ^ (i - 1) * 4
            Case "5": B = B + 16 ^ (i - 1) * 5
            Case "6": B = B + 16 ^ (i - 1) * 6
            Case "7": B = B + 16 ^ (i - 1) * 7
            Case "8": B = B + 16 ^ (i - 1) * 8
            Case "9": B = B + 16 ^ (i - 1) * 9
            Case "A": B = B + 16 ^ (i - 1) * 10
            Case "B": B = B + 16 ^ (i - 1) * 11
            Case "C": B = B + 16 ^ (i - 1) * 12
            Case "D": B = B + 16 ^ (i - 1) * 13
            Case "E": B = B + 16 ^ (i - 1) * 14
            Case "F": B = B + 16 ^ (i - 1) * 15
        End Select
    Next i
    HEX_to_DEC = B
End Function以下是dll的结构体格式!
typedef struct {
short datatype;
short treatflag;

int date;
int record;
char dbid[4+1];
char serverno;
short iSourceFileNum;
} TRANSMITMESSAGEHEAD;typedef struct {
union {
struct {
short sign;
short type;
};
char suffix[4];
};
int length;
} SOURCE_HEAD;
代码有些烦,但主要看蓝色行声明是否正确;红色行第一个参数格式和类型是否有问题,其余代码都是在拼这个参数,肯定没错。程序执行到红色行会报错,dll的调用约定错误!十分头疼,请高人指教!

解决方案 »

  1.   

    可能太繁琐了,没人回我。简化一下问题:
    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As String, ByVal iDataBufLen As Long) As Long
    Private Type TRANSMITMESSAGEHEAD
            datatype As Integer
            treatflag As Integer
            date As Long
            record As Long
            dbid(4) As Byte
            serverno As Byte
            iSourceFileNum As Integer
    End TypePrivate Type SOURCE_HEAD
            suffix(3) As Byte
            Length As Long
    End Type
    Private Headstructure As TRANSMITMESSAGEHEAD
    Private HeadSource As SOURCE_HEAD这是dll的函数说明!
    int SendData(char *sDataBuf, int iDataBufLen);state1 = SendData(sDataBuf()), 129)
    这样调用为什么报错!
      

  2.   

    各位高人,我再重新说明一下:我需要在vb中调用一个dll,dll的说明文档里是这样说的: 
    以下是dll的结构体格式! 
    typedef struct { 
    short datatype; 
    short treatflag; int date; 
    int record; 
    char dbid[4+1]; 
    char serverno; 
    short iSourceFileNum; 
    } TRANSMITMESSAGEHEAD; typedef struct { 
    union { 
    struct { 
    short sign; 
    short type; 
    }; 
    char suffix[4]; 
    }; 
    int length; 
    } SOURCE_HEAD; 
    这是dll的函数说明! 
    int SendData(char *sDataBuf, int iDataBufLen); 
    其中第一个参数是上面两个结构体之和,我首先要在vb中填好这两个结构体的内容,再放进这第一个参数里。我是这样做的:
    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As String, ByVal iDataBufLen As Long) As Long 
    Private Type TRANSMITMESSAGEHEAD 
            datatype As Integer 
            treatflag As Integer 
            date As Long 
            record As Long 
            dbid(4) As Byte 
            serverno As Byte 
            iSourceFileNum As Integer 
    End Type Private Type SOURCE_HEAD 
            suffix(3) As Byte 
            Length As Long 
    End Type 
    Private Headstructure As TRANSMITMESSAGEHEAD 
    Private HeadSource As SOURCE_HEAD 
    Dim sDataBuf() As Byte 
    这里填sDataBuf,然后:
    state1 = SendData(sDataBuf()), 129) 
    这样调用为什么报错!
      

  3.   

    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As Long, ByVal iDataBufLen As Long) As Long ....
    state1 = SendData(VarPtr(sDataBuf(0)), 129)
      

  4.   

    对不起,高手,情况是这样的。我已经改成这样了:
    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As Long, ByRef iDataBufLen As Long) As Long 
    state1 = SendData(sDataBuf, 129)
    这样的话和您给的答案
    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As Long, ByVal iDataBufLen As Long) As Long ....
    state1 = SendData(VarPtr(sDataBuf(0)), 129)
    执行结果是一样的,vb遇到问题需要关闭!原来的错已经没有了!请问这是怎么回事?
      

  5.   

    对不起,高手,情况是这样的。我已经改成这样了:
    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As String, ByRef iDataBufLen As Long) As Long 
    state1 = SendData(sDataBuf, 129)
    这样的话和您给的答案
    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As Long, ByVal iDataBufLen As Long) As Long ....
    state1 = SendData(VarPtr(sDataBuf(0)), 129)
    执行结果是一样的,vb遇到问题需要关闭!原来的错已经没有了!请问这是怎么回事?
      

  6.   

     ByRef传的是指针,传简单数据类型一般用传值的方式
      

  7.   

    在VC中,参数或者变量带*号的,都是需要传递指针
    像你的问题,把API声明中的参数写成:Private Declare Function SendData Lib "SendData.dll" (sDataBuf As Any, ByVal iDataBufLen As Long) As Long'参数传递的时候可以这样试试:
    state1 = SendData(sDataBuf(0), 129)
      

  8.   

    Private Declare Function SendData Lib "SendData.dll" (ByVal sDataBuf As Long, ByVal iDataBufLen As Long) As Long .... 
    state1 = SendData(VarPtr(sDataBuf(0)), 129) 
    对不起,才上.是这样的,最后的结果是这样的,用这样的方法还是报dll调用约定错误,但是生成exe之后,用exe执行不会报错,而且执行结果是正常的,就是调试的时候还会报错,不知道为什么?
      

  9.   

    如果C中的函数的确声明成__stdcall,那么应该是函数内的某些操作与VB-IDE冲突,用API就是这样,只要保证exe运行正确就可以了,很多时候是无法调试的。
      

  10.   

    调试的时候用的SendData.dll与你生成exe后的路径是一样的吗?