DELPHI7 函数原型
function SetDoorGuardPeriods(hPort: THandle; Fun: Byte;  ts: array of TDoorTimePeriods;Count:Integer; week: Byte=0): Boolean;stdcall;
VC6 定义原型
typedef BOOL (PASCAL *ECSetDoorGuardPeriods)(HANDLE hPort, byte Fun,TDoorTimePeriods *ts,const int Count, const byte week=0);
BOOL bSuc = SetDoorGuardPeriods(m_hComHandle,Fun,ts,Count,week);
结果:样本 Vc6调用  :SetDoorGuardPeriods(1900,1,ts[1],1,0)
          DLL传入 :1900,1,ts[2],13012481,96问题 1 count \week两个数据不对
     2 ts的长度与count相关 len(ts) = count+1
还请各位高手指点一二!谢谢

解决方案 »

  1.   

    delphi下的array of TDoorTimePeriods
    在VC中没有对应的数据类型的
    建议修改为DELPHI7 函数原型 
    function SetDoorGuardPeriods(hPort: THandle; Fun: Byte;  ts: PChar; Count:Integer; week: Byte): Boolean;stdcall; 
    VC6 定义原型 
    typedef BOOL (PASCAL *ECSetDoorGuardPeriods)(HANDLE hPort, byte Fun,TDoorTimePeriods *ts,const int Count, const byte week); 
    BOOL bSuc = SetDoorGuardPeriods(m_hComHandle,Fun,ts,Count,week); 传递地址方式传TDoorTimePeriods的内容
      

  2.   

    这个函数参数设置得有问题啊,前面的ts是变长的,后面的参数你叫dll里怎样取啊,肯定有问题啦,应该按楼上的改,而且,将count放到ts前面好理解些,设计函数也要有一定的罗辑嘛
      

  3.   

    TDoorTimePeriods是由五个int类型的结构体,用PCHAR不合适,count的数量已经定义了,只是现在VC调用后count的值传过来就错了.
    谢谢各位
      

  4.   

    用PChar其实也就是个指针而已,要不就改为无类型指针Pointer
    结果:样本 Vc6调用  :SetDoorGuardPeriods(1900,1,ts[1],1,0) 
              DLL传入 :1900,1,ts[2],13012481,96 从你这个可看出,调用完全混乱了,核心还是array of TDoorTimePeriods 这个参数的问题,VC并没有匹配的类型,
    这里还涉及数据对齐的问题,delphi的结构默认是8位对齐的。传递的数据要做到字节匹配。尤其是跨语言调用设计到非标准数据类型的参数,最好还是用指针传递。
    这样的设计也是Windows API常用的。
      

  5.   

    function SetDoorGuardPeriods(hPort: THandle; Fun: Byte; ts: ^TDoorTimePeriods;
      Count: Integer; week: Byte = 0): Boolean; stdcall;

    function SetDoorGuardPeriods(hPort: THandle; Fun: Byte; ts: ^TDoorTimePeriods;
      Count: Integer; week: Byte = 0): Boolean; pascal;
    试试看哪个是对的
      

  6.   

    是不是调用协定写得不一样?我不懂VB,但是看你的声明,调用协定似乎是PASCAL。而DELPHI的调用协定是STDCALL
      

  7.   

    function SetDoorGuardPeriods(hPort: THandle; Fun: Byte; var ts: array of TDoorTime;Periods;Count:Integer; week: Byte=0): Boolean;pascal; 
      

  8.   

    function SetDoorGuardPeriods(hPort: THandle; Fun: Byte; var ts: array of TDoorTime;Periods;Count:Integer; week: Byte=0): Boolean;pascal;  
    也改了,还是不对。
    我把count\week的顺序也提前了,结果这两个参数的值是取对了,但是在最后返回结果值的时候出错:
    ---------------------------
    Microsoft Visual C++ Debug Library
    ---------------------------
    Debug Error!Program: D:\我的文档\桌面\自动测试程序\自动测试程序\test.exe
    Module: 
    File: i386\chkesp.c
    Line: 42The value of ESP was not properly saved across a function call.  This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention. (Press Retry to debug the application)
    ---------------------------
    终止(A)   重试(R)   忽略(I)   
    ---------------------------
      

  9.   

    楼主还是没弄明白,咋样在不同语言之间调用DLL在不同语言之间调用DLL,关键在于要用两种语言都支持的数据格式对于VC来说,dephi的数据类型 var ts: array of TDoorTime ,就没有对应的数据类型对数据结构TDoorTime 来说,会有对应的数据类型但 array of TDoorTime来说,vc是没有对应的数据类型的。
      

  10.   

    trainbox
    非常感谢你的提醒,对这个问题的理解我一直都不是很深入。
    关于这个array of 调用,我一直认为在底层实现与指针是一样的。
      

  11.   

    在同事的帮助下,终于解决了,解决的方式如下:
    typedef BOOL  (PASCAL *ECSetDoorGuardPeriods)(HANDLE hPort, byte Fun,TDoorTimePeriods &ts,int cnt, int Count, byte week);
    在不动delphi的定义前提下,如上定义.
    function SetDoorGuardPeriods(hPort: THandle; Fun: Byte;  ts: array of TDoorTimePeriods;Count:Integer; week: Byte=0): Boolean;stdcall; 对比下,将会发现如上定义多了一个参数。cnt,这个参数是用来传递了Ts的数组。
    后记:这个函数的定义成这样,就有点累赘了,因为有了2个count,不过遵循DLL不动的原则,只能如此解决了。最后谢谢各位兄弟的帮忙。VC和汇编不懂,不能解决底层问题!教训