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,如果是单独运行编译后的程序的话,什么提示也没有,程序就直接退出了。
我想了想,问题可能是出在函数转化的地方,类型可能用得不对。请大家帮我看看,谢谢
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,如果是单独运行编译后的程序的话,什么提示也没有,程序就直接退出了。
我想了想,问题可能是出在函数转化的地方,类型可能用得不对。请大家帮我看看,谢谢
解决方案 »
- CodeGear开发者日,Delphi 2007
- 我用ACCESS做数据库,用sql查询,备注字段显示乱码
- 火箭两连胜.....散分100.....
- 在MDI里,怎么使两个子窗体不能同时打开?
- Access like通配符的问题
- 简单问题~!求教高手!
- 请问哪里有摩托车竞速游戏 Road Rash 完全版下载?
- ×××Delphi中如何实现VC中Ondraw()的自动刷新功能(高手帮帮我啊!)×××
- ----- 放分了 ---- 请各位谈谈 如果老板让你51(或者10.1)加班你会怎样?
- 许久没上CSDN,本人近期遇到一个十分苦恼的问题!送分200!
- 如何将Excel表中内容导入数据库中
- ScrollBox
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.
usint 是自己定义的对应 unsigned short 与 delphi 中 word类型是一致的。
把stdcall换成cdecl后工作正常了
应该是stdcall方式传过去的参数bcin被释放了,当再次访问该变量时出错。
具体不是太清楚,那位朋友讲讲
_cdecl:C\C++的缺省调用协议,由调用者清理堆栈,这就是C\C++中可以使用可变参数的函数的原因,所有参数自右至作入栈,生成的代码中函数名有一个_做前缀
_stdcall:Win32 API的调用协议,由被调用的函数清理堆栈,所有参数自右至左入栈,生成的代码中函数名有一个_做前缀和一个@和参数的总字节数(十进制)作后缀。它不支持可变参数,但它产生的代码比_cdecl短,因为没有每次调用后的清理堆栈的代码。
stdcall由被调用方清理stack,cdecl由调用方清理,调用方和被调用方没对应上的结果就是函数返回的地址跑飞了
C++中如果
WORD BCIN00[32]; 這也是DLL處的寫法
那在 Delphi 中最好 array[0..32-1] of Word ; //
這個應該是調用方式的問題,可能是由於讓被調用方清理了堆栈造成的。
var
data:array[0..xxx] of Word;
begin
Load_BC_Datablk_MCH(XXX, blknum, wdcnt, @data[0]);
end;
请看下原贴,我用了两种方式调用都不行
原因是没搞清楚stdcal和cdecl的区别
stdcall由被调用方清理stack,cdecl由调用方清理,调用方和被调用方没对应上的结果就是函数返回的地址跑飞了