Getlist是回调函数,由vc编写的dll主动发起
这是vc下的函数写法,调用没问题
void GetList(int count, PVEH_INFO info)
{
char buffer[30];
CString sCount ="";
CString sAxisType ="";
CString sWeight ="";
CString sSpeed ="";
CString sMsg;
for (int i=0;i<count;i++)
{
_itoa(i+1,buffer,10);
sCount = buffer;
_itoa(info[i].axistype,buffer,10);
sAxisType = buffer;
_ltoa(info[i].weight,buffer,10);
sWeight = buffer;
_ltoa(info[i].speed,buffer,10);
sSpeed = buffer;
sMsg += " 车号:" + sCount + " 轴类型:" + sAxisType + "    轴重:" + sWeight + "    轴速:" + sSpeed +"\n";
}
AfxMessageBox(sMsg);
return;
}
这是在delphi中的函数写法,一调用就崩溃
procedure GetList(Count: Integer; Info: PVeh_Info); stdcall;
var
  I: Integer;
  //P: PVeh_Info;
  a: PInfoArray;
begin
  a := PInfoArray(Info);
  //P := Info;
  Form1.ListBox1.Items.Clear;
  for I:=0 to Count-1 do
  begin
    with Form1.ListBox1 do
    begin
      Items.Add(Format('Weight=%d, AxisType=%d, Speed=%.1f',[a^[i].weight, a^[i].axistyep, a^[i].speed]));
      //Items.Add(Format('Weight=%d, AxisType=%d, Speed=%.2f',[P^.weight, P^.axistyep, P^.speed]));
    end;
    //P := Pointer(Longint(Info) + SizeOf(Veh_Info));
  end;
end;
但是如果自己发送数据给delphi下的getlist函数也没问题
procedure TForm1.SList(Sender: TObject);
var
  tp: array of Veh_Info;
  tempStr: string;
begin
  SetLength(tp,2);
  tp[0].weight := 1000;
  tp[0].axistyep := 11;
  tp[0].speed := 12.3;
  tp[1].weight := 28950;
  tp[1].axistyep := 115;
  tp[1].speed := 19.1;
  tempStr := '固定发送第一组数据为: 1000,11,12.3' + #13#10 +
             '                第二组数据为: 28950,115,19.1';
  ShowMessage(tempStr);
  getList(2,PVeh_Info(tp));
end;end.请高手指点
干脆把dll中回调的部分也写出来,供大家分析void CWtSerialPort::CallBackList(void)
{
    int iCount;
CMSG msg;
    POSITION pos;
    long vehicleWeight=0; // 总重
long lAxisType=0;  // 轴型 (满足输出需要)
    int j=0; // 轴组序号
    int buf[10]; // 保存轴组类型 例如 buf[1]=1 buf[2]=2 buf[3]=2  iCount=(int)m_MsgQueue.GetCount(); // 缓冲区中总车数
    VEH_INFO *pVEH_INFO;                   // 定义结构指针
pVEH_INFO = new VEH_INFO[iCount];      // 建立结构数组 

if (iCount==0)                         // 缓冲区中没有数据

return;
}
else
{
//pVEH_INFO->weight = 2;                       
//pVEH_INFO->axistype = 3;
//pVEH_INFO->speed = 4;
//pVEH_INFO+1;
for (int k=0;k<iCount;k++)  // 缓冲区中的车辆依次转换
{
    pos = m_MsgQueue.FindIndex(k);
     msg = m_MsgQueue.GetAt(pos);//取出最早的一辆车
  for (int i=0;i<msg.axisNum;i++)  // 依次判断各个单轴,根据单轴在轴组中的轴型计算轴组载荷
  {
  if (msg.pAxisType[i]==1 || msg.pAxisType[i]==2) // 如果是一个轴的轴组
  {
  // tempAxisType=msg.pAxisType[i]; 
  buf[j]=msg.pAxisType[i];     // 保存轴组类型   
  //pVEH_INFO[k].weight=msg.pAxisWeight[i]; // 总重
  vehicleWeight+=msg.pAxisWeight[i];
  }
              if (msg.pAxisType[i]>2 && msg.pAxisType[i]<6) // 如果是双联轴
  {  
  //tempAxisType+=msg.pAxisType[i];
                  buf[j]=msg.pAxisType[i];
  vehicleWeight+=msg.pAxisWeight[1]+msg.pAxisWeight[i+1]; //两个单轴重量和 
  i++;  // 跳过双联轴的第二个单轴
  }
  if (msg.pAxisType[i]>5 && msg.pAxisType[i]<8) // 如果是三联轴
  {
                  //tempAxisType+=msg.pAxisType[i];
                  buf[j]=msg.pAxisType[i];
  vehicleWeight+=msg.pAxisWeight[i]+msg.pAxisWeight[i+1]+msg.pAxisWeight[i+2];// 三个单轴重量和
  i++; // 跳过三联轴的第二个单轴
  i++; // 跳过三联轴的第三个单轴
  }
 // pVEH_INFO->axistype =sprintf("%l",tempAxisType); //轴型
     // 车速
  j++; //轴组序号+1
     }
  for (int m=0;m<j;m++)
  {
             // 将轴组数组转换为long变量 例如:轴组类型为122 ,数组为buf[1][2][2],转换为122 
 lAxisType+=buf[m]*(long)pow(double(10),j-m-1); // 122= 1*10*10+2*10+2*1
  }
  // pVEH_INFO+=msg.pAxisGroupType[msg.axisGroupNum];  
          // 结构赋值 两种方法 1.pVEH_INFO[k]直接对象应的数组元素赋值
  //                  2.pVEH_INFO赋值,然后pVEH_INFO+1指向下一个元素(但必须保证最后传入
  //                    回调函数的时候pVEH_INFO指向第一个元素,否则每次只传入最后一个数组元素
  pVEH_INFO[k].axistype =lAxisType;  
  pVEH_INFO[k].weight =vehicleWeight;
  pVEH_INFO[k].speed =msg.speed;
  // 轴组序号清零 整车重清零 轴组类型清零 
  j=0;
  vehicleWeight=0;
  lAxisType=0;
}   
     p_CallBackListFunc(iCount,pVEH_INFO);// 将车辆数组传递    
}
}vc
p_CallBackListFunc(iCount,pVEH_INFO);// 将车辆数组传递delphi
getList(2,PVeh_Info(tp));我想这就是问题关键所在,请大家指点,多谢了

解决方案 »

  1.   

    是不是和_cdecl 与 stdcall(pascal)有关?
      

  2.   

    void CWtSerialPort::CallBackList(void)
    改成
    void __stdcall void CWtSerialPort::CallBackList(void)
    试试。
    delphi 一般函数调用协定是PASCALL 也就是vc的__stdcall (注意是二根下划线)
      

  3.   

    上面多打了一个void,应该是:
    void __stdcall CWtSerialPort::CallBackList(void)
      

  4.   

    调用约定一定要注意
    __stdcall?
      

  5.   

    问题解决,回调函数定义
    没有加__stdcall,给分