VC头文件中函数原型为
int __declspec(dllexport) Load_BC_Datablk_MCH(int, usint blknum, usint wdcnt, usint *data);
调用过程为

        WORD BCIN00[32]; BCIN00[0] =0x4004;
BCIN00[1] =0x0180;
BCIN00[2] =0;
        BCIN00[3] =0;
BCIN00[4] =0;;
BCIN00[5] =0;;
BCIN00[6] =0;; Load_BC_Datablk_MCH(m_nhandle, 1,18,BCIN00);我转成了Delphi的
Function Load_BC_Datablk_MCH(hBus : THandle; BlkNum, wdcnt : WORD; var Data :  WORD) : Integer; stdcall; external 'MCHMS.DLL' name 'Load_BC_Datablk_MCH';  

Function Load_BC_Datablk_MCH(hBus : THandle; BlkNum, wdcnt : WORD; Data : Array of WORD) : Integer; stdcall; external 'MCHMS.DLL' name 'Load_BC_Datablk_MCH';
调用过程
BCIN : Array[0..31] of WORD; BCIN[0] := $4004;
BCIN[1] := $0180;
BCIN[2] := 0;
   BCIN[3] := 0;
   BCIN[4] := 0;
   BCIN[5] := 0;
   BCIN[6] := 0;
Load_BC_Datablk_MCH(hBus, 1, 18, BCIN);或者
Load_BC_Datablk_MCH(hBus, 1, 18, BCIN[0]);函数返回值都是0,表示函数成功返回了。但程序执行是总是提示Access violation,如果是单独运行编译后的程序的话,什么提示也没有,程序就直接退出了。
我想了想,问题可能是出在函数转化的地方,类型可能用得不对。请大家帮我看看,谢谢

解决方案 »

  1.   

    Function Load_BC_Datablk_MCH(hBus : THandle; BlkNum, wdcnt : WORD; 
                                                      Data : PWordArray) : Integer; stdcall; 
                          external 'MCHMS.DLL' name 'Load_BC_Datablk_MCH';
     Array of WORD换成 PWordArray试试
    PWordArray TWordArray (declared in SysUtils). Used to typecast dynamically allocated memory for arrays of 2-byte values.Delphi syntax:type 
      PWordArray = ^TWordArray;
      TWordArray = array[0..16383] of Word;C++ syntax:typedef Word TWordArray[16384];DescriptionTWordArray declares a general array of type Word that can be used in typecasting.
      

  2.   

    C++中的usint应该对应Delphi中的Longword,楼主最好将参数的类型保持一致。
      

  3.   


    usint 是自己定义的对应 unsigned short 与 delphi 中 word类型是一致的。
    把stdcall换成cdecl后工作正常了
    应该是stdcall方式传过去的参数bcin被释放了,当再次访问该变量时出错。
    具体不是太清楚,那位朋友讲讲
    _cdecl:C\C++的缺省调用协议,由调用者清理堆栈,这就是C\C++中可以使用可变参数的函数的原因,所有参数自右至作入栈,生成的代码中函数名有一个_做前缀   
        
    _stdcall:Win32 API的调用协议,由被调用的函数清理堆栈,所有参数自右至左入栈,生成的代码中函数名有一个_做前缀和一个@和参数的总字节数(十进制)作后缀。它不支持可变参数,但它产生的代码比_cdecl短,因为没有每次调用后的清理堆栈的代码。
      

  4.   

    array of Word这种参数类型别乱写,比一般的多压一个High(arrayVar),stdcall保证call一次挂一次
    stdcall由被调用方清理stack,cdecl由调用方清理,调用方和被调用方没对应上的结果就是函数返回的地址跑飞了
      

  5.   


    C++中如果
    WORD BCIN00[32]; 這也是DLL處的寫法
    那在 Delphi  中最好  array[0..32-1] of Word ;  // 
      

  6.   

    函数返回值都是0,表示函数成功返回了。但程序执行是总是提示Access violation,如果是单独运行编译后的程序的话,什么提示也没有,程序就直接退出了。 
    這個應該是調用方式的問題,可能是由於讓被調用方清理了堆栈造成的。
      

  7.   

    stdcall会在退出时清空堆栈,但是调用函数在堆栈中压入了参数占用了位置,这些位置将由调用函数负责清空。如果参数个数未知,函数在编译期就不知到底要在堆栈里清除多少个字节,这样_stdcall就不能用了,有些函数只能使用Pascal调用约定,函数不会清空堆栈,cdecl就是谁调用谁清理,恢复堆栈,可以理解成前者把破摊子丢给别人,后者自己闯的祸自己解决
      

  8.   

    最后一个参数类型可以用Pointer,使用时可以如下:
    var
      data:array[0..xxx] of Word;
    begin
      Load_BC_Datablk_MCH(XXX, blknum, wdcnt, @data[0]);
    end;
      

  9.   

    你的BCIN[0]是第一个元素的内容,而不是这个数组的地址,远函数的这个参数实际需要的是这个数组的起始地址!!!!!
      

  10.   


    请看下原贴,我用了两种方式调用都不行
    原因是没搞清楚stdcal和cdecl的区别
    stdcall由被调用方清理stack,cdecl由调用方清理,调用方和被调用方没对应上的结果就是函数返回的地址跑飞了