Delphi 将字符串参数传递给 IDispatch.Invoke
Delphi pass string parameter to IDispatch.Invoke
使用 Delphi 11.1,我想使用 IActiveScript 向我的应用程序添加脚本。我创建了一个小的 VBScript 来测试从 Delphi 传递到脚本的参数:
function test2(n)
MsgBox n
test2 = n
end function
VBScript 代码加载正常,传递整数作为参数工作正常,但是当传递字符串参数时,我发现只有字符串的前半部分进入脚本。 Delphi代码:
procedure TForm1.Button4Click(Sender: TObject);
var
Disp: IDispatch;
Res: OleVariant;
DispParams: TDispParams;
s: string;
n: Integer;
v: Variant;
Arg: array of TVariantArg;
begin
OleCheck(FScript.GetScriptDispatch(nil, Disp));
s := 'test2';
OleCheck(Disp.GetIDsOfNames(GUID_NULL, @s, 1, 1033, @n));
v := VarArrayOf(['1234567890']);
SetLength(Arg, VarArrayHighBound(v, 1) - VarArrayLowBound(v, 1) + 1);
arg[0].vt := VT_BSTR;
arg[0].bstrVal := PWideChar(VarToStr(v[0])); //passes first half of string only
// arg[0].bstrVal := SysAllocString(PWideChar(VarToStr(v[0]))); //passes complete (copy of) string
end;
DispParams.rgvarg := @Arg[0];
DispParams.rgdispidNamedArgs := nil;
DispParams.cArgs := 1;
DispParams.cNamedArgs := 0;
//at this point, debugger shows no difference, bstrVal holds full string
OleCheck(Disp.Invoke(n, GUID_NULL, 1033, DISPATCH_METHOD, DispParams, @res, nil, nil));
end;
MsgBox 显示 12345。尝试了其他字符串,其他字符串长度,也总是只有前半部分。
谁能对此有所启发?
与 COM 接口时,您需要使用 WideString
(COM BSTR
字符串的包装器)而不是使用 string
(又名 UnicodeString
),例如:
procedure TForm1.Button4Click(Sender: TObject);
var
Disp: IDispatch;
Res: OleVariant;
DispParams: TDispParams;
s: WideString;
n: Integer;
v: Variant;
Arg: array of TVariantArg;
begin
OleCheck(FScript.GetScriptDispatch(nil, Disp));
s := 'test2';
OleCheck(Disp.GetIDsOfNames(GUID_NULL, @s, 1, 1033, @n));
v := VarArrayOf(['1234567890']);
SetLength(Arg, VarArrayHighBound(v, 1) - VarArrayLowBound(v, 1) + 1);
s := VarToWideStr(v[0]);
arg[0].vt := VT_BSTR;
arg[0].bstrVal := PWideChar(s);
//arg[0].bstrVal := SysAllocString(PWideChar(s));
DispParams.rgvarg := @Arg[0];
DispParams.rgdispidNamedArgs := nil;
DispParams.cArgs := 1;
DispParams.cNamedArgs := 0;
OleCheck(Disp.Invoke(n, GUID_NULL, 1033, DISPATCH_METHOD, DispParams, @res, nil, nil));
//SysFreeString(arg[0].bstrVal);
end;
使用 Delphi 11.1,我想使用 IActiveScript 向我的应用程序添加脚本。我创建了一个小的 VBScript 来测试从 Delphi 传递到脚本的参数:
function test2(n) MsgBox n test2 = n end function
VBScript 代码加载正常,传递整数作为参数工作正常,但是当传递字符串参数时,我发现只有字符串的前半部分进入脚本。 Delphi代码:
procedure TForm1.Button4Click(Sender: TObject);
var
Disp: IDispatch;
Res: OleVariant;
DispParams: TDispParams;
s: string;
n: Integer;
v: Variant;
Arg: array of TVariantArg;
begin
OleCheck(FScript.GetScriptDispatch(nil, Disp));
s := 'test2';
OleCheck(Disp.GetIDsOfNames(GUID_NULL, @s, 1, 1033, @n));
v := VarArrayOf(['1234567890']);
SetLength(Arg, VarArrayHighBound(v, 1) - VarArrayLowBound(v, 1) + 1);
arg[0].vt := VT_BSTR;
arg[0].bstrVal := PWideChar(VarToStr(v[0])); //passes first half of string only
// arg[0].bstrVal := SysAllocString(PWideChar(VarToStr(v[0]))); //passes complete (copy of) string
end;
DispParams.rgvarg := @Arg[0];
DispParams.rgdispidNamedArgs := nil;
DispParams.cArgs := 1;
DispParams.cNamedArgs := 0;
//at this point, debugger shows no difference, bstrVal holds full string
OleCheck(Disp.Invoke(n, GUID_NULL, 1033, DISPATCH_METHOD, DispParams, @res, nil, nil));
end;
MsgBox 显示 12345。尝试了其他字符串,其他字符串长度,也总是只有前半部分。
谁能对此有所启发?
与 COM 接口时,您需要使用 WideString
(COM BSTR
字符串的包装器)而不是使用 string
(又名 UnicodeString
),例如:
procedure TForm1.Button4Click(Sender: TObject);
var
Disp: IDispatch;
Res: OleVariant;
DispParams: TDispParams;
s: WideString;
n: Integer;
v: Variant;
Arg: array of TVariantArg;
begin
OleCheck(FScript.GetScriptDispatch(nil, Disp));
s := 'test2';
OleCheck(Disp.GetIDsOfNames(GUID_NULL, @s, 1, 1033, @n));
v := VarArrayOf(['1234567890']);
SetLength(Arg, VarArrayHighBound(v, 1) - VarArrayLowBound(v, 1) + 1);
s := VarToWideStr(v[0]);
arg[0].vt := VT_BSTR;
arg[0].bstrVal := PWideChar(s);
//arg[0].bstrVal := SysAllocString(PWideChar(s));
DispParams.rgvarg := @Arg[0];
DispParams.rgdispidNamedArgs := nil;
DispParams.cArgs := 1;
DispParams.cNamedArgs := 0;
OleCheck(Disp.Invoke(n, GUID_NULL, 1033, DISPATCH_METHOD, DispParams, @res, nil, nil));
//SysFreeString(arg[0].bstrVal);
end;