Problem with Delphi transfer - OLE (RsLinx OPC, Group Adding work only from constants)

We got an OPC job. I cannot install RsLinx in my Win7 (and XP mode too) due to errors, so I am sending my test application to a real place, and someone is testing it.

Since I don't have a DLL, I cannot make the Delphi interface, so I only need to make OLE calls.

I had an interesting problem with Group Add.

I demonstrate this:

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;

The result is:

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

So the problem is that I cannot add any group than a constant ...

I need to know how Delphi compiles this constant in order to convert the value of this variant into this format.

Can someone help me on this topic?

Thanks: dd


Hello!

So, the problem is mysterious. I found another error in pure OLE calls.

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 ...: - (

, , ( Q). TLB , Delphi7 ( Win7 Delphi6 OLE), Kassl.

...

:   

+3
3

, OleString/BSTR (WideString). ... , .

  • OPCGroups.Add? ?
  • ? , .

Edit:

.

, :

  • , Delphi , , , .
  • .

:

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, .. . , .

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

, , Delphi , Add(). :

ws: = WideString (s);

. WideString, .

ws: = s;

.

0

You do not need to reinvent the wheel. There are many libraries, examples, and sample code on how to use OPC with Delphi. For free Delphi OPC servers and clients, see here: http://www.opcconnect.com/delphi.php .

0
source

Source: https://habr.com/ru/post/1777643/


All Articles