3

OPCの仕事に就きました。エラーのためにRsLinxをWin7(およびXPモードも)にインストールできないため、テストアプリを実際の場所に送信し、誰かがテストします。

DLLがないため、Delphiインターフェイスを作成できません。そのため、OLE呼び出しのみを実行する必要があります。

GroupAddで興味深い問題が発生しました。

私はそれを示します:

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は機能していません... :-(

それで、私は風車との戦いを続けないと決めました(ドンQ)。Delphi7を使用している親愛なるユーザーからTLBを入手しました(Win7ではDelphi6はOLEインターフェイスを生成できません)。Kasslを見つけました。

これらのインターフェースが私を助けてくれますように...

ありがとう:dd

4

3 に答える 3

0

私の知る限り、定数と文字列はすべてOleString / BSTR(WideString)に変換されます。しかし、あなたはこれらの問題を抱えているので...おそらくそうではありません。

  1. OPCGroups.Addのドキュメントは何と言っていますか?何が期待されますか?
  2. タイプライブラリはありますか?たぶん、それらをインポートして、インターフェースを直接使用することができます。

編集:

ドキュメントはあまり明確ではありません。

試すことができることがいくつかあります。

  1. CPUビューで、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-libraryにバグがあるようです。

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);
于 2010-11-30T19:37:29.490 に答える
0

コードにはいくつかの問題があります。また、使用しているDelphiのバージョンと、Add()呼び出しが使用するパラメーターの種類を知っておくと便利です。とにかくいくつかのヒント:

ws:= WideString(s);

それは間違った型キャストです。文字列をWideStringに変換するのではなく、メモリをそのように解釈するように強制します。使用する

ws:= s;

コンパイルは、変換ルーチンを呼び出すように注意します。

于 2010-11-30T19:41:04.333 に答える
0

車輪を発明する必要はありません。DelphiでOPCを使用する方法については、多くのライブラリ、例、およびサンプルコードがあります。無料のDelphiOPCサーバーとクライアントについては、http ://www.opcconnect.com/delphi.phpをご覧ください。

于 2010-12-01T11:22:38.333 に答える