用VS写的动态库,Delphi写的上位机。其他接口调用都没问题,动态库和上位机分别编译也没问题。但是动态库回调上位机的回调函数时,弹出“access violation at addressXXXX ,write of addressXXXX”
上位机和动态库中分别的操作是:
上位机中:
回调函数声明TOnResponse =procedure(sCmdBack:PChar) of object;回调函数有声明,有定义。
调用回调函数的接口函数function RegisterHWCallback(aCallback:TOnResponse):Integer;stdcall;external 'Hardware.dll';
动态库中:
回调函数声明typedef void (*TOnResponse)(PCHAR sCmdBack);
调用回调函数的接口函数extern"C"_declspec(dllexport)int _stdcall RegisterHWCallback(TOnResponse aCallback)一旦进入该接口函数,即使里面是空操作,跳出这个接口函数时都会弹出“access violation at addressXXXX ,write of addressXXXX”
这个问题解决思路是什么,之前为这个动态库写过vs的上位机,都没问题。但是链接上对方的Delphi上位机后就弹出了这个问题。
上位机和动态库中分别的操作是:
上位机中:
回调函数声明TOnResponse =procedure(sCmdBack:PChar) of object;回调函数有声明,有定义。
调用回调函数的接口函数function RegisterHWCallback(aCallback:TOnResponse):Integer;stdcall;external 'Hardware.dll';
动态库中:
回调函数声明typedef void (*TOnResponse)(PCHAR sCmdBack);
调用回调函数的接口函数extern"C"_declspec(dllexport)int _stdcall RegisterHWCallback(TOnResponse aCallback)一旦进入该接口函数,即使里面是空操作,跳出这个接口函数时都会弹出“access violation at addressXXXX ,write of addressXXXX”
这个问题解决思路是什么,之前为这个动态库写过vs的上位机,都没问题。但是链接上对方的Delphi上位机后就弹出了这个问题。
解决方案 »
- TbsSkinXFormButton,TbsSkinButton,TbsSkinSpeedButton的使用问题
- 给介绍一个文本编辑控件,多谢了!
- 截取Richedit上显示成为图片及滚动指定行
- 请问在Delphi中如何使用动态图标
- 如何把图片存进SQL2000在读出来,请给个例子
- 请问调试自定义component的技巧
- 请大家爱关注一下的问题!!有关报表连接查询
- 什么是TNotifyEvent和TIndexEvent?
- 通过IDPOP3收取邮件邮件保存到本地,如何判断哪些是未收取的新邮件
- 各位兄台,我即将跳楼,不要拉我
- 有个源码,没有delphi 2007 求帮忙编译下!
- Delphi7和firebird数据库的连接问题
这里有of object啊!跟动态库的声明对应不上吧?
改成:
TOnResponse =procedure(sCmdBack:PChar) ; cdecl;
你的Delphi程序中,TOnResponse =procedure(sCmdBack:PChar) of object;这声明了一个方法指针,由于你没有指出调用约定,默认是Borland的register约定,所以对这个回调函数正确的参数传入是:eax=self(C++中的this),edx=sCmdBack,函数自己做栈平衡;而你的VC代码中定义的,typedef void (*TOnResponse)(PCHAR sCmdBack);使用cdecl调用约定,sCmdBack使用栈传递,调用者做栈平衡。
你看看两者能不能对上?整个就是猴吃麻花---满拧。如果你非要在C代码中调用Delphi的方法,那你就不能直接用函数指针调用,要自己写一个调用转换函数,比如:
void CallBackThunk(TOnResponse &P, PCHAR sCmdBack);
在其内部用嵌入汇编模拟方法指针调用,但是C代码并不知道被调用方法的实例指针,这也是一个严重隐患,所以最好还是把Delphi的回调函数定义改一下。
TOnResponse =procedure(sCmdBack:PChar) of object;对应VC动态库里要怎么声明才能与这个方法指针对应呢
这样的话参数传递问题解决了,主要问题在于C代码并不知道被调用方法的实例指针,你还得修改RegisterHWCallback把它传给C代码:
int _stdcall RegisterHWCallback(TOnResponse aCallback, void *Sender);
这个Sender你得保存起来,调用Delphi回调函数的时候要用到:
typedef void (__stdcall *TOnResponse)(Void *Sender, PCHAR sCmdBack);