You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Delphi向C++ DLL传递函数指针后调用参数异常问题排查

问题根源:调用约定不匹配

你的问题出在Delphi和C++两端的函数调用约定不一致,导致参数传递机制冲突,进而读取到错误的参数值。

具体修改方案

C++端代码调整

需要明确指定函数指针的调用约定为_stdcall,和setFoo本身的调用约定保持一致:

void (_stdcall *foo)(int);
extern "C" void _stdcall setFoo(void (_stdcall *foo2)(int))
{
    foo = foo2;
    foo(1);
}

Delphi端代码调整

  1. 把TFoo类型和fooH函数都指定为stdcall调用约定,和C++端匹配;
  2. 确保TSetFoo的参数类型和调整后的TFoo一致:
TFoo = procedure(val: integer); stdcall;
TSetFoo = procedure(val: TFoo); stdcall;
...
Foo: TFoo;
SetFoo:TSetFoo;

...

procedure fooH(val: integer); stdcall;
begin
  ShowMessage('foo '+IntToStr(val));
end;
...
setFoo(fooH);

为什么这样改?

  • Delphi默认的过程调用约定是register,会用EAX、EDX、ECX寄存器传递前三个参数;
  • C++中未指定调用约定的函数指针默认是cdecl,而你的setFoo用的是_stdcall,stdcall会通过栈传递所有参数,且由被调用者负责清理栈;
  • 两者调用约定不匹配时,参数传递的位置完全错位,C++端调用时读取到的是栈上的垃圾数据,所以会显示巨大的数值。

内容的提问来源于stack exchange,提问作者vico

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.14 07:20:53