gpt4 book ai didi

string - Delphi - OLE 变体传递问题(RsLinx OPC,组添加仅使用常量)

转载 作者:行者123 更新时间:2023-12-03 18:00:02 26 4
gpt4 key购买 nike

我们得到了 OPC 工作。由于错误,我无法将 RsLinx 安装到我的 Win7(和 XP 模式),所以我将我的测试应用程序发送到真实的地方,并有人测试它。

因为没有DLL,不能做Delphi界面,所以只能做OLE Calls。

我在添加组时遇到了一个有趣的问题。

我演示一下:

procedure TForm1.Button8Click(Sender: TObject);
var
r, g : variant;
s : string;
v : variant;
ws : WideString;
begin
Log('Connect');
r := CreateOleObject('RSI.OPCAutomation');
r.Connect('RSLinx OPC Server');

Log('Add as constant');
g := r.OPCGroups.Add('MONKEY_C');
Log('Name ' + g.Name);

Log('Add as string');
s := 'MONKEY_S';
g := r.OPCGroups.Add(s);
Log('Name ' + g.Name);

Log('Add as variant');
s := 'MONKEY_V';
v := s;
g := r.OPCGroups.Add(v);
Log('Name ' + g.Name);

Log('Add as ole variant');
s := 'MONKEY_OV';
v := VarAsType(s, varOleStr);
g := r.OPCGroups.Add(v);
Log('Name ' + g.Name);

Log('Add as widestring');
s := 'MONKEY_WS';
ws := WideString(s);
g := r.OPCGroups.Add(ws);
Log('Name ' + g.Name);

Log('Add as widestring var');
s := 'MONKEY_WSV';
ws := WideString(s);
v := ws;
g := r.OPCGroups.Add(v);
Log('Name ' + g.Name);

r := 0;

end;

结果是:

Connect
Add as constant
Name MONKEY_C
Add as string
Name _Group0
Add as variant
Name _Group1
Add as ole variant
Name _Group2
Add as widestring
Name _Group3
Add as widestring var
Name _Group4

所以我无法添加常量定义之外的任何组的问题...

我需要知道 Delphi 如何将此常量编译为我可以将我的变量值转换为此格式。

谁能帮我解决这个主题?

感谢: dd


嗨!

所以这个问题很玄乎。我在纯 OLE 调用中发现了另一个错误。

function TDDRsOPCObject.IndexOfGroup(GroupName: string): integer;
var
ogs, g : variant;
i : integer;
s : string;
begin
CheckObject;
Result := -1;
ogs := FObj.OPCGroups;
s := '';
for i := 1 to ogs.Count do begin
g := ogs.Item(i); // This is working
if AnsiCompareText(g.Name, GroupName) = 0 then begin
Result := i;
Exit;
end;
end;
end;


function TDDRsOPCObject.GetGroupByName(GroupName: string): variant;
var
idx : integer;
ogs, g : variant;
begin
CheckObject;
VarClear(Result);
idx := IndexOfGroup(GroupName);
ogs := FObj.OPCGroups;
if idx <> -1
then begin
g := ogs.Item(idx); // HERE I GOT: The parameter is incorrect
Result := g;
end;
end;

所以很有趣:具有相同调用的 IndexOfGroup 正在工作,GetGroupByName 不是... :-(

所以我决定不再继续与风车战斗(Don Q)。我从一位拥有 Delphi7 的亲爱的用户那里得到了 TLB(在 Win7 中,Delphi6 无法生成 OLE 接口(interface)),我找到了 Kassl。

希望这些接口(interface)可以帮助我...

感谢: dd

最佳答案

据我所知,常量和字符串都被转换为 OleString/BSTR (WideString)。但是既然你有这些问题......可能不会。

  1. OPCGroups.Add 的文档说了什么?期望什么?
  2. 你有类型库吗?也许您可以导入它们并直接使用界面。

编辑:

文档不是很清楚。

有几件事你可以尝试:

  1. 在 CPU View 中检查 Delphi 编译器如何处理带有常量的代码,也许您会在那里看到一些关于如何处理字符串的提示。
  2. 试试这个代码。

代码:

const
OPC_GROUP_NAME: WideString = 'MONKEY_C';
<...>
g := r.OPCGroups.Add(OPC_GROUP_NAME);
Log('Name ' + g.Name);

当上面的代码工作时,试试这个:

const
{$J+} //writable constants on
OPC_GROUP_NAME: WideString = 'dummy';
{$J-}
<...>
OPC_GROUP_NAME := 'MONKEY_BLA';
g := r.OPCGroups.Add(OPC_GROUP_NAME);
Log('Name ' + g.Name); //should be: 'Name MONKEY_BLA'

注意:我不喜欢第 2 步,但如果它有效……为什么不呢。在我看来,您使用的 com 库中似乎存在错误。

编辑2:

我查看了使用常量和使用普通字符串生成的代码。对于常量,我看到第一个字符的地址被压入堆栈,对于字符串,我看到指向字符串的指针的地址被压入堆栈。

使用下面的代码,我可以模拟与常量相同的行为:

var
lWideArray: array[0..40] of WideChar;
s: string;
i: Integer;
<..>
s := 'MONKEY_FOO';
for i := 0 to Length(lWideArray) - 1 do
begin
if i < Length(s) then
lWideArray[i] := WideChar(s[i+1])
else
lWideArray[i] := #0;
end;

g := r.OPCGroups.Add(WideString(lWideArray));
Log('Name ' + g.Name);

关于string - Delphi - OLE 变体传递问题(RsLinx OPC,组添加仅使用常量),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/4313304/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com