VS回调Delphi上位机回调函数的问题

xihuanbilan 2014-09-17 09:22:45
用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上位机后就弹出了这个问题。
...全文
707 7 打赏 收藏 转发到动态 举报
写回复
用AI写文章
7 条回复
切换为时间正序
请发表友善的回复…
发表回复
  • 打赏
  • 举报
回复
引用 6 楼 xihuanbilan 的回复:
如果上位机和动态库都改成stdcall的调用约定。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);
xihuanbilan 2014-09-18
  • 打赏
  • 举报
回复
如果上位机和动态库都改成stdcall的调用约定。Delphi程序中依然声明方法指针 TOnResponse =procedure(sCmdBack:PChar) of object;对应VC动态库里要怎么声明才能与这个方法指针对应呢
s11ss 2014-09-17
  • 打赏
  • 举报
回复
TOnResponse =procedure(sCmdBack:PChar) of object; 这里有of object啊!跟动态库的声明对应不上吧?
  • 打赏
  • 举报
回复
抱歉,那做不到,除非你让微软把编译器改了。 你的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的回调函数定义改一下。
xihuanbilan 2014-09-17
  • 打赏
  • 举报
回复
抱歉,是改动态库,不改上位机。动态库是VS写的。
  • 打赏
  • 举报
回复
TOnResponse =procedure(sCmdBack:PChar) of object; 改成: TOnResponse =procedure(sCmdBack:PChar) ; cdecl;
xihuanbilan 2014-09-17
  • 打赏
  • 举报
回复
那改动态库的话,动态库里的声明应当怎么写啊

1,183

社区成员

发帖
与我相关
我的任务
社区描述
Delphi Windows SDK/API
社区管理员
  • Windows SDK/API社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧