LabVIEWForum.de
prodave dll in lv aufrufen - Druckversion

+- LabVIEWForum.de (https://www.labviewforum.de)
+-- Forum: LabVIEW (/Forum-LabVIEW)
+--- Forum: LabVIEW Allgemein (/Forum-LabVIEW-Allgemein)
+---- Forum: DLL & externer Code (/Forum-DLL-externer-Code)
+---- Thema: prodave dll in lv aufrufen (/Thread-prodave-dll-in-lv-aufrufen)



prodave dll in lv aufrufen - vanbasten - 08.03.2013 11:10

Hallo,
ich habe erfolgreich mittels Prodave eine Verbindung zu einer SoftPLC (ACCONtrol S7) aufgebaut. In C++ sieht der Code folgendermassen aus:
Code:
//load connection (automatically sets as active)
    int loadConRV = 0; //return value
    unsigned short conNr = 0; //ID
    char* accessPoint = "S7ONLINE"; //default, as opposed to MPI
    CON_TABLE_TYPE conTable[MAX_CONNECTION+1]; //CON_TABLE_TYPE conTable; works as well to simplify LV access
    CON_TABLE_TYPE* pConTable = &conTable[conNr]; //&conTable; works as well to simplify LV access
    unsigned short conTableLen = sizeof(CON_TABLE_TYPE);
    pConTable[conNr].Adr.Ip[0] = 127; //IP irrelevant for softplc
    pConTable[conNr].Adr.Ip[1] = 0;
    pConTable[conNr].Adr.Ip[2] = 0;
    pConTable[conNr].Adr.Ip[3] = 1;
    pConTable[conNr].AdrType = 2; //IP
    pConTable[conNr].SlotNr = 2;
    pConTable[conNr].RackNr = 0;
    loadConRV = LoadConnection_ex6(conNr, accessPoint, conTableLen, pConTable);
    printf("LoadConnection() return value: %x\n", loadConRV);

Nun versuche ich dasselbe mit lv11_img unter WinXP 32-bit. Die Funktion lässt sich nicht importieren, weil unter den Parametern union innerhalb struct vorkommt. Ausschnitt aus dem Prodave-Manual:
Code:
int LoadConnection_ex6 (int ConNr, char* pAccessPoint, int ConTableLen,
CON_TABLE_TYPE * pConTable);
Parameters
ConNr
[in] Number of the connection (max. 64 connections).
pAccessPoint
[in] access point (zero-terminated) of the driver used, e.g. "S7ONLINE" for the MPI
driver or 0 (default).
ConTableLen
[in] length of the connection structure provided by the user in bytes
pConTable
[in] pointer to address structure of the user
#pragma pack(1)
typedef union {
unsigned char Mpi; // MPI/PB station address (2)
unsigned char Ip[4]; // IP address (192.168.0.1)
unsigned char Mac[6]; // MAC address (08-00-06-01-AA-BB)
} CON_ADR_TYPE;
typedef struct {
CON_ADR_TYPE Adr; // connection address
unsigned char AdrType; // Type of address: MPI/PB (1), IP (2), MAC (3)
unsigned char SlotNr; // Slot number
unsigned char RackNr; // Rack number
} CON_TABLE_TYPE;
#pragma pack(1)

Ich habe mir bereits folgende Seite angeschaut. Man soll theoretisch die Parameter eines Structs einzeln nacheinander auflisten. Jedoch mein Code verursacht einen Absturz von LV..

Im Anhang findet ihr das Beispiel. Für jede Hilfe wäre ich dankbar.


RE: prodave dll in lv aufrufen - rolfk - 08.03.2013 11:52

(08.03.2013 11:10 )vanbasten schrieb:  Hallo,
ich habe erfolgreich mittels Prodave eine Verbindung zu einer SoftPLC (ACCONtrol S7) aufgebaut. In C++ sieht der Code folgendermassen aus:
Code:
//load connection (automatically sets as active)
    int loadConRV = 0; //return value
    unsigned short conNr = 0; //ID
    char* accessPoint = "S7ONLINE"; //default, as opposed to MPI
    CON_TABLE_TYPE conTable[MAX_CONNECTION+1]; //CON_TABLE_TYPE conTable; works as well to simplify LV access
    CON_TABLE_TYPE* pConTable = &conTable[conNr]; //&conTable; works as well to simplify LV access
    unsigned short conTableLen = sizeof(CON_TABLE_TYPE);
    pConTable[conNr].Adr.Ip[0] = 127; //IP irrelevant for softplc
    pConTable[conNr].Adr.Ip[1] = 0;
    pConTable[conNr].Adr.Ip[2] = 0;
    pConTable[conNr].Adr.Ip[3] = 1;
    pConTable[conNr].AdrType = 2; //IP
    pConTable[conNr].SlotNr = 2;
    pConTable[conNr].RackNr = 0;
    loadConRV = LoadConnection_ex6(conNr, accessPoint, conTableLen, pConTable);
    printf("LoadConnection() return value: %x\n", loadConRV);

Nun versuche ich dasselbe mit lv11_img unter WinXP 32-bit. Die Funktion lässt sich nicht importieren, weil unter den Parametern union innerhalb struct vorkommt. Ausschnitt aus dem Prodave-Manual:
Code:
int LoadConnection_ex6 (int ConNr, char* pAccessPoint, int ConTableLen,
CON_TABLE_TYPE * pConTable);
Parameters
ConNr
[in] Number of the connection (max. 64 connections).
pAccessPoint
[in] access point (zero-terminated) of the driver used, e.g. "S7ONLINE" for the MPI
driver or 0 (default).
ConTableLen
[in] length of the connection structure provided by the user in bytes
pConTable
[in] pointer to address structure of the user
#pragma pack(1)
typedef union {
unsigned char Mpi; // MPI/PB station address (2)
unsigned char Ip[4]; // IP address (192.168.0.1)
unsigned char Mac[6]; // MAC address (08-00-06-01-AA-BB)
} CON_ADR_TYPE;
typedef struct {
CON_ADR_TYPE Adr; // connection address
unsigned char AdrType; // Type of address: MPI/PB (1), IP (2), MAC (3)
unsigned char SlotNr; // Slot number
unsigned char RackNr; // Rack number
} CON_TABLE_TYPE;
#pragma pack(1)

Ich habe mir bereits folgende Seite angeschaut. Man soll theoretisch die Parameter eines Structs einzeln nacheinander auflisten. Jedoch mein Code verursacht einen Absturz von LV..

Im Anhang findet ihr das Beispiel. Für jede Hilfe wäre ich dankbar.

pConTable ist ein Pointer auf eine struct, nicht die struct selber. Demgemäss musst Du die Elemente dieser struct nicht einzeln als Funktionsparameter übergeben, sondern als struct. Und man kann das in LabVIEW machen indem man einen Cluster erstellt der mit dieser struct kompatibel ist und dann den Call Library Node Parameter als Adapt to Type konfiguriert und den Cluster dort anschliesst.

Der Cluster sollte 6 Bytes für CON_ADR_TYPE enthalten (der Size des grössten Unionelementes) und dann je ein Byte für die anderen drei Elemente. Und bitte die 6 Bytes als 6 seperate Bytes anlegen (möglicherweise als ein Subcluster) aber sicher nicht als Array.

Und der erste Parameter ist ein int, das ist ein 32 bit Integer, kein 16 bit Integer wie in Deinem VI. int == 16 bit war voor Urzeiten mit DOS!!

Übrigens ist das pragma pack(1) in der Prodav-Beschreibung erstens überflüssig da alle Elemente in der struct sowieso byte sized sind und zweitens ziemlich sicher auch falsch, da man üblicherweise das pragma am Ende mit einem Aufruf ohne Parameter wieder auf default zurücksetzt und nicht einfach nochmals auf den selben Wert setzt wie zuvor.


RE: prodave dll in lv aufrufen - vanbasten - 08.03.2013 12:44

Danke für die Antwort. Ich habe gerade die Cluster-Variante ausprobiert und den Integer-Fehler behoben. Bei der Einstellung von Adapt to Type bin ich mir nicht sicher, ob "Handles durch Wert" das korrekte Datenformat ist. Leider stürzt LV immer noch ab, könnte es an den Namen der Cluster liegen?

Von der oben genannten Webseite habe ich auch ein Beispiel der Verwendung der Cluster, jedoch dort sieht das Blockdiagramm völlig anders aus (Parameter ist jedoch Cluster, nicht Pointer auf Cluster).

PS. Fehler im Prodave-Manual sind leider nichts Neues..

Ich füge die Dateien hinzu und bitte erneut um Tipps.


RE: prodave dll in lv aufrufen - rolfk - 08.03.2013 14:00

(08.03.2013 12:44 )vanbasten schrieb:  Danke für die Antwort. Ich habe gerade die Cluster-Variante ausprobiert und den Integer-Fehler behoben. Bei der Einstellung von Adapt to Type bin ich mir nicht sicher, ob "Handles durch Wert" das korrekte Datenformat ist. Leider stürzt LV immer noch ab, könnte es an den Namen der Cluster liegen?

Die einstellung Handles By Value ist nur relevant when der Parameter ein LabVIEW Array oder String ist und das ist nur sinnvoll wenn die DLL spezifisch dafür programmiert ist um mit solchen Datentypen umzugehen. Standard DLLs sind das NIE!

Die Anpassung des Controls auf dem Frontpanel nach int32 ist zwar schön und gut aber völlig irrelevant. Es geht um die Anpassung des Parameters in der Call Library Node. Und wenn Du schon dabei bist, der dritte Parameter ist auch ein int!

Ansonsten sehe ich so auf die Schnelle keine Probleme die mir direkt ins Auge stechen würden ausser vielleicht: Bist Du Dir sicher das die S7 Steuerung die Du ansprechen willst unter localhost (127.0.0.1) vom Computer aus ansprechbar ist? Aber das sollte eigentlich nicht crashen.