# LibNoDave



## SPS_PC (8 Mai 2009)

Hallo,

ich möchte mir mit der libnodave.dll ein Delphi Programm zum Auslesen einzelner SPS-Bausteine schreiben. Mit welcher Funktion ist das möglich,
und wie wird der Aufruf am besten durchgeführt.


Ich verwende eine S7-300 mit Ethernet CP und Delphi 7.


Danke im Voraus


----------



## jabba (8 Mai 2009)

Gibt doch ein Beispiel dafür, muss aber etwas angepasst werden.
Mit Nodavedemo erst einmal die Verbindung testen.

Mit welcher Funktion hängt davon ab was Du lesen willst.


----------



## SPS_PC (8 Mai 2009)

Das Beispeil habe ich leider nicht gefunden.

Die Verbindung funktioniert mit den Delphi-Demo.

Ich möchte OB's, FC's und FB's auslesen.


----------



## jabba (8 Mai 2009)

Ich habe bisher nur daten damit gelesen, laut Beschreibung kann er aber auch Programmcode lesen und schreiben.

Demo ist unter DelphiComponent/Demo/Delphi wenn du die Library geladen hast.


----------



## SPS_PC (9 Mai 2009)

Danke das Beispiel hab ich jetzt gefunden.
Das lesen von Daten funktionert.

Ich habe mir mal die nodave.pas und die nodavecomponent.pas angeschaut. 

Habe dabei folgende Funktionen in der nodave.pas entdeckt
initupload, doupload und endupload.
Sind das die richtigen zum auslesen von OB's und FC's? Wenn ja wie werden sie eingesetzt?

Gibt es auch solle Funktionen der in nodavecomponent.pas?
Konnte darin keine vergleichbaren finden.


----------



## SPS_PC (12 Mai 2009)

Ich denke die Funktionen sind richtig.

Die dem Beispiel beiliegende Komponente habe ich um folgende Funktion erweitert


```
// Read PLC-Program-Block
function  TNoDave.ReadPLCPrg(blockType:char; blockNr:longint):longint;
var
  WasActive : Boolean;
  res       : longint;
  upID,
  len,
  more      :longint;
  sError    : string;
  Buf         : ppuc;
  Data        : string;
  i           : Integer;
begin
  WasActive:=Active;
  Active:=True;
  // Transfer von SPS nach PC starten
  LockNoDave.Enter;
  res := initUpload(daveConn, blockType, blockNr, @upID);
  LockNoDave.Leave;
  // Transfer ausführen
  New(Buf);
  Buf^ := AllocMem(1024);
  more := 0;
  len  := 0;
  if res = daveResOK then
    begin
      // Blöcke lesen
      LockNoDave.Enter;
      repeat
        res := doUpload(daveConn, @more, @Buf, @len, upID);
        if res <> daveResOK then
          begin
            LockNoDave.Leave;
            Dispose(Buf);
            SError := daveStrerror(abs(res));
            result := res;
            exit;
          end;
      until more <= 0;
      LockNoDave.Leave;
      // Transfer beenden
      endUpload(DaveConn, upID);
    end;
  Data := '';
  for i := 0 to len - 1 do
    Data := Data + pUC(Integer(Pointer(Buf^)) + i)^;
  Dispose(Buf);
  result := res;
  Active:=WasActive;
end;
```
 
Funktionert leider nicht richtig. Ich vermutet das Problem liegt
in der Übergabe des Parameters "Buf". Hat jedem Erfahrung mit
der Parameterübergabe von Delphi an C-Routine mit dem Type
"Zeiger auf Zeiger auf Char"?


----------



## marcengbarth (16 Mai 2009)

Wie rufst du die Funktion denn auf?


----------



## Ralle (16 Mai 2009)

Ich hab immer ein Array für Buf definiert. Dieses passe ich bei Bedarf dynamisch in der Länge an.


----------



## SPS_PC (19 Mai 2009)

Danke für die Hilfe,

ich habe jetzt auch einen Weg gefunden, die Funktionsparameter so zu
übergeben das es funktioniert.


----------

