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

Delphi调用IActiveScript IDispatch.Invoke传递多参数异常问题

出错原因

问题根源是悬空指针和不规范的COM变体操作,具体两点:

  1. 临时对象生命周期问题:VarToWideStr(v[i])返回的是临时WideString值,将其内部字符指针赋值给Arg[n].bstrVal后,临时对象会在当前语句执行结束、或进入下一次循环迭代时被Delphi自动释放,bstrVal随即成为指向已回收内存的野指针。这就是参数值重复、运行结果随机、32/64位表现不一致的直接原因——野指针指向的内存内容不受控,会随着内存复用随时变化。单参数场景下临时对象释放后内存暂时未被覆写,所以看起来运行正常,参数数量增加后内存被反复复用,问题就会稳定复现。
  2. 不符合COM VARIANT操作规范:TVariantArg是COM标准VARIANTARG结构的Delphi映射,直接手动修改vt和bstrVal字段,既没有正确初始化结构的保留字段,也没有按照COM要求为BSTR分配独立内存、维护引用计数。你注释里手动赋值常量字符串能运行只是巧合:常量字符串存储在程序静态只读段,生命周期和程序一致,不会被释放,本质依然是不规范写法,传入动态字符串必然出错。

另外你代码里@Arg报错是正常的:Delphi动态数组本身是指向数组首元素的指针,@Arg取到的是动态数组变量自身的地址,不是数组内容的首地址,@Arg[0]的写法才是正确的。

修复方法

不要手动操作TVariantArg的底层字段,使用Delphi内置的变体操作函数处理参数,自动完成类型转换、内存分配和释放,修复后的核心代码如下:

procedure TForm1.Button14Click(Sender: TObject);
var
  v: OleVariant;
  Disp: IDispatch;
  Arg: TArray<TVariantArg>;
  Res: OleVariant;
  DispParams: TDispParams;
  i, n: Integer;
  s: WideString;
  dispid: TDispID;
begin
  v := VarArrayOf(['Wrong...', 'huh', 'OK!']);
  s := 'TestParams';

  OleCheck(MyScriptingHost1.FScript.GetScriptDispatch(nil, Disp));
  OleCheck(Disp.GetIDsOfNames(GUID_NULL, @s, 1, 1033, @dispid));

  // 按实际参数个数初始化参数数组
  SetLength(Arg, VarArrayHighBound(v, 1) - VarArrayLowBound(v, 1) + 1);
  // COM规范要求Invoke的参数按逆序存入rgvarg数组
  for i := VarArrayLowBound(v, 1) to VarArrayHighBound(v, 1) do
  begin
    n := High(Arg) - i;
    // 初始化变体结构,直接赋值OleVariant自动处理内存和类型
    VariantInit(TVarData(Arg[n]));
    OleVariant(Arg[n]) := v[i];
  end;

  DispParams.rgvarg := @Arg[0];
  DispParams.rgdispidNamedArgs := nil;
  DispParams.cArgs := Length(Arg);
  DispParams.cNamedArgs := 0;

  OleCheck(Disp.Invoke(dispid, GUID_NULL, 1033, DISPATCH_METHOD, DispParams, @Res, nil, nil));
  
  // 调用完成后释放参数中的变体资源,避免内存泄漏
  for i := 0 to High(Arg) do
    VariantClear(TVarData(Arg[i]));

  Memo2.Lines.Text := VarToStr(Res);
end;

修复后传参逻辑在32位、64位环境下表现一致,支持任意数量、任意自动化兼容类型的参数传递,不会出现随机值问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 21:09:58