用VC写了两个API函数给VB调用:int WINAPI ADD(int a,int b)
VARIANT WINAPI GetInfo()函数GetInfo返回二为数组,其中使用到SAFEARRAY安全数组编译成DLL后VB中声明使用,运行VB编写程序,第一次调用 GetInfo结果正常,再一次调用GetInfo出错(提示内存不可读),关闭该程序再重新调用,又提示同样错误。而多次调用ADD函数没有这个问题。我在VC中调试调用这个VB编写到程序,连续调用GetInfo函数都没有问题,
请各位帮忙解释什么原因,如何解决,我不想做成ATL,是不是VARIANT等不应该在这种方式下使用?

解决方案 »

  1.   

    sorry ,
    i can't help you .
      

  2.   

    VARIANT WINAPI GetLog(int MachineID)
    {

    VARIANT pArray;
    pArray.vt=VT_NULL;
    if(m_pComm==NULL) //串口未打开
    {
    return pArray;
    }
    char chSend[10]; //令牌报文AD1 AD2 AD3 AD4 ML MH TY CRC1 CRC2
    int i=0;
    int iSendLen=0; //发送长度
    BYTE* pBuff;
    _bstr_t tmpVar;
    long ltmp;
    short itmp;
    char sztmp[16]; memset(chSend,0,sizeof(chSend));
    iSendLen=10; //发送数据长度,去报表时发送长度为10
    //指纹机地址
    chSend[2]=LOBYTE(MachineID); //取低位
    chSend[3]=HIBYTE(MachineID); //取高位
    //发送数据长度分两个字节分别存储
    //chSend[4]=LOBYTE(iSendLen);
    //chSend[5]=HIBYTE(iSendLen);
    memcpy(chSend+4,&iSendLen,2);
    chSend[6]=0x50;
    pBuff=(BYTE*)malloc(1); //分配读取到的数据缓冲去,一个字节,在CSerialComm::ReadData有分配
    i=m_pComm->SendData(chSend,sizeof(chSend)); //发出读取日志命令
    Sleep(100);
    i=m_pComm->ReadData(pBuff); //i为读到的字节数 if(i<=0)
    {
    free(pBuff);
    return pArray;
    }

    //memcpy((void*)&i, (BYTE*)(pBuff + 7), 2); //取得数据长度

    i=(i - 10)/16; //获得的字节数-10(固定报头格式的)/16,在指纹机中一个日志结构为16个字节
    if(i==0)
    {
    return pArray; //得不到数据返回空数组
    } /*****************此处加入CRC校验*************\
    |*  *|
    |* CRC  *|
    |*  *|
    \*********************************************/ BSTR bstrTemp;
    SAFEARRAY* psa; //定义数组描述符
    SAFEARRAYBOUND bound[2]; //二维数组
    bound[0].cElements=5; //列
    bound[0].lLbound=0;
    bound[1].cElements=i; //行
    bound[1].lLbound=0; psa = SafeArrayCreate( VT_BSTR, 2, bound );//创建数组
    long lDimension[2];

    for(int n = 0; n < i; n++)
    {

    //得到日期
    memcpy((void*)&ltmp, pBuff + 10 + n*16, 4);
    sprintf(sztmp, "%2.2u-%2.2u-%2.2u", (ltmp>>16)&0xFFFF, (ltmp>>8)&0xFF, ltmp&0xFF);
    tmpVar = sztmp;
    //得到时间
    memcpy((void*)&ltmp, pBuff + 14 + n*16, 4);
    sprintf(sztmp, "%2.2u:%2.2u:%2.2u", (ltmp>>16)&0xFF, (ltmp>>8)&0xFF, ltmp&0xFF);
    tmpVar = tmpVar + " " + sztmp;
    lDimension[0]=0;
    lDimension[1]=n;
    bstrTemp = SysAllocString(tmpVar);
    //SafeArrayPutElement(psa,lDimension,tmpVar.copy()); //这样写法tmpVar有内存泄漏
    SafeArrayPutElement(psa,lDimension,bstrTemp); //数组赋值,必须是BSTR型
    SysFreeString(bstrTemp);

    //取UserID
    memcpy((void*)&itmp, pBuff + 18 + n*16, 2);
    tmpVar=itmp;
    lDimension[0]=1;
    lDimension[1]=n;
    bstrTemp = SysAllocString(tmpVar);
    SafeArrayPutElement(psa,lDimension,bstrTemp); //数组赋值,必须是BSTR型
    SysFreeString(bstrTemp);

    //取Code
    memcpy((void*)&itmp, pBuff + 20 + n*16, 2);
    tmpVar=itmp;
    lDimension[0]=2;
    lDimension[1]=n;
    bstrTemp = SysAllocString(tmpVar);
    SafeArrayPutElement(psa,lDimension,bstrTemp); //数组赋值,必须是BSTR型
    SysFreeString(bstrTemp);

    //取Val
    memcpy((void*)&itmp, pBuff + 22 + n*16, 2);
    tmpVar=itmp;
    lDimension[0]=3;
    lDimension[1]=n;
    bstrTemp = SysAllocString(tmpVar);
    SafeArrayPutElement(psa,lDimension,bstrTemp); //数组赋值,必须是BSTR型
    SysFreeString(bstrTemp);

    //取Spare
    memcpy((void*)&itmp, pBuff + 24 + n*16, 2);
    tmpVar=itmp;
    lDimension[0]=4;
    lDimension[1]=n;
    bstrTemp = SysAllocString(tmpVar);
    SafeArrayPutElement(psa,lDimension,bstrTemp); //数组赋值,必须是BSTR型
    SysFreeString(bstrTemp);
    }
    pArray.vt = VT_ARRAY | VT_BSTR; //VARIANT类型定义,BSTR型数组
    pArray.parray = psa; //数组
    free(pBuff);
    return pArray;
    }
      

  3.   

    以上的GetLog(int MachineID)返回二维数组,问题就出在这个函数里面,这个函数主要掉了一个串口通讯类,我还没有试试到底问题出在哪里,也许在串口通讯类里面
      

  4.   

    问题解决:将数据返回行参
    i=m_pComm->ReadData(pBuff); 改为函数返回如
    pBuff=m_pComm->ReadData(&i)主要是内存分配问题