Delphi - OLE变体传递问题(RsLinx OPC,Group Add仅使用常量)

时间:2010-11-30 11:40:16

标签: string delphi ole opc

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

因为我没有DLL,所以我无法创建Delphi接口,所以我只需要进行OLE调用。

Group Add。我遇到了一个有趣的问题。

我证明了这一点:

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接口),我找到了Kassl。

这些界面可以帮助我......

感谢:     DD

3 个答案:

答案 0 :(得分:0)

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

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

    文档不是很清楚。

    您可以尝试一些事项:

    1. 检查CPU查看Delphi编译器使用常量编写的代码,也许你会看到一些关于如何处理字符串的提示。
    2. 试试这段代码。
    3. 代码:

      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库中有一个错误。

      <强> EDIT2:

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

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

      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);
      

答案 1 :(得分:0)

您的代码中存在一些问题,也很高兴知道您正在使用哪个版本的Delphi,以及Add()调用使用的参数类型。无论如何一些提示:

ws:= WideString(s);

这是一个错误的类型转换。它不会将您的字符串转换为WideString,它只会强制将内存解释为此类。使用

ws:= s;

编译将注意调用转换例程。

答案 2 :(得分:0)

你不必发明轮子。有很多库,示例和示例代码如何使用OPC和Delphi。对于免费的Delphi OPC服务器和客户端,请查看此处:http://www.opcconnect.com/delphi.php