Snap7 Undefined Reference to TS7Client::TS7Client()
-
This is my .pro file
QT += core gui
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
TARGET = untitled1
TEMPLATE = appDEFINES += QT_DEPRECATED_WARNINGS
SOURCES +=
main.cpp
mainwindow.cpp
snap7.cppHEADERS +=
mainwindow.h \FORMS +=
mainwindow.uiwin32: LIBS += -L$$PWD/./ -lsnap7
INCLUDEPATH += $$PWD/.
DEPENDPATH += $$PWD/. -
into .h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> //#include "snap7.h" class TS7Client; namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); void CliCompletion(void *usrPtr, int opCode, int opResult); void SysSleep(uint32_t Delay_ms); bool Check(int Result, const char * function); void MultiRead(); void ListBlocks(); void OrderCode(); void CpuInfo(); void CpInfo(); void UnitStatus(); void UploadDB0(); void AsCBUploadDB0(); void AsEWUploadDB0(); void AsPOUploadDB0(); void ReadSzl_0011_0000(); bool CliConnect(); void CliDisconnect(); void PerformTests(); void Summary(); //void hexdump(void *mem, unsigned int len); ~MainWindow(); private: Ui::MainWindow *ui; TS7Client *Client; uint8_t Buffer[65536]; // 64 K buffer int SampleDBNum = 1000; char *Address = (char*)"192.168.0.1" ; // PLC IP Address int Rack=0,Slot=1; // Default Rack and Slot int ok = 0; // Number of test pass int ko = 0; // Number of test failure bool JobDone=false; int JobResult=0; }; #endif // MAINWINDOW_H
into .cpp
#include "mainwindow.h" #include "ui_mainwindow.h" #include <stdio.h> #include <stdlib.h> #include "QThread" #include "QString" #include "snap7.h" MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent),ui(new Ui::MainWindow) { ui->setupUi(this); TS7Client *abc = new TS7Client(); if (CliConnect()) { PerformTests(); CliDisconnect(); } delete Client; Summary(); } void MainWindow::CliCompletion(void *usrPtr, int opCode, int opResult) { JobResult=opResult; JobDone = true; } /**********************************************************************************************/ // SysSleep (copied from snap_sysutils.cpp) multiplatform millisec sleep //------------------------------------------------------------------------------ void MainWindow::SysSleep(longword Delay_ms) { QThread::msleep(Delay_ms); } bool MainWindow::Check(int Result, const char *function) { ui->textEdit->append("\n"); ui->textEdit->append("+-----------------------------------------------------\n"); ui->textEdit->append(function); ui->textEdit->append("+-----------------------------------------------------\n"); if (Result==0) { ui->textEdit->append("| Result : OK\n"); ui->textEdit->append("| Execution time : " + QString::number(Client->ExecTime())); ui->textEdit->append("+-----------------------------------------------------\n"); ok++; } else { ui->textEdit->append("| ERROR !!! \n"); if (Result<0) ui->textEdit->append("| Library Error (-1)\n"); else ui->textEdit->append(tr("| %1").arg(CliErrorText(Result).c_str())); ui->textEdit->append("+-----------------------------------------------------\n"); ko++; } return Result==0; } void MainWindow::MultiRead() { // Multiread buffers byte MB[16]; // 16 Merker bytes byte EB[16]; // 16 Digital Input bytes byte AB[16]; // 16 Digital Output bytes word TM[8]; // 8 timers word CT[8]; // 8 counters // Prepare struct TS7DataItem Items[5]; // NOTE : *AMOUNT IS NOT SIZE* , it's the number of items // Merkers Items[0].Area =S7AreaMK; Items[0].WordLen =S7WLByte; Items[0].DBNumber =0; // Don't need DB Items[0].Start =0; // Starting from 0 Items[0].Amount =16; // 16 Items (bytes) Items[0].pdata =&MB; // Digital Input bytes Items[1].Area =S7AreaPE; Items[1].WordLen =S7WLByte; Items[1].DBNumber =0; // Don't need DB Items[1].Start =0; // Starting from 0 Items[1].Amount =16; // 16 Items (bytes) Items[1].pdata =&EB; // Digital Output bytes Items[2].Area =S7AreaPA; Items[2].WordLen =S7WLByte; Items[2].DBNumber =0; // Don't need DB Items[2].Start =0; // Starting from 0 Items[2].Amount =16; // 16 Items (bytes) Items[2].pdata =&AB; // Timers Items[3].Area =S7AreaTM; Items[3].WordLen =S7WLTimer; Items[3].DBNumber =0; // Don't need DB Items[3].Start =0; // Starting from 0 Items[3].Amount =8; // 8 Timers Items[3].pdata =&TM; // Counters Items[4].Area =S7AreaCT; Items[4].WordLen =S7WLCounter; Items[4].DBNumber =0; // Don't need DB Items[4].Start =0; // Starting from 0 Items[4].Amount =8; // 8 Counters Items[4].pdata =&CT; int res=Client->ReadMultiVars(&Items[0],5); if (Check(res,"Multiread Vars")) { // Result of Client->ReadMultivars is the "global result" of // the function, it's OK if something was exchanged. // But we need to check single Var results. // Let shall suppose that we ask for 5 vars, 4 of them are ok but // the 5th is inexistent, we will have 4 results ok and 1 not ok. ui->textEdit->append("Dump MB0..MB15 - Var Result : " + QString::number(Items[0].Result)); // if (Items[0].Result==0) // hexdump(&MB,16); ui->textEdit->append("Dump EB0..EB15 - Var Result : " + QString::number(Items[1].Result)); // if (Items[1].Result==0) // hexdump(&EB,16); ui->textEdit->append("Dump AB0..AB15 - Var Result : " + QString::number(Items[2].Result)); // if (Items[2].Result==0) // hexdump(&AB,16); ui->textEdit->append("Dump T0..T7 - Var Result : " + QString::number(Items[3].Result)); /*if (Items[3].Result==0) hexdump(&TM,16); */ // 8 Timers -> 16 bytes ui->textEdit->append("Dump Z0..Z7 - Var Result : " + QString::number(Items[4].Result)); // if (Items[4].Result==0) // hexdump(&CT,16); // 8 Counters -> 16 bytes } } void MainWindow::ListBlocks() { TS7BlocksList List; int res=Client->ListBlocks(&List); if (Check(res,"List Blocks in AG")) { ui->textEdit->append(" OBCount : "+ QString::number(List.OBCount)); ui->textEdit->append(" FBCount : "+ QString::number(List.FBCount)); ui->textEdit->append(" FCCount : "+ QString::number(List.FCCount)); ui->textEdit->append(" SFBCount : "+ QString::number(List.SFBCount)); ui->textEdit->append(" SFCCount : "+ QString::number(List.SFCCount)); ui->textEdit->append(" DBCount : "+ QString::number(List.DBCount)); ui->textEdit->append(" SDBCount : "+ QString::number(List.SDBCount)); } } void MainWindow::OrderCode() { TS7OrderCode Info; int res=Client->GetOrderCode(&Info); if (Check(res,"Catalog")) { ui->textEdit->append(tr("Order Code : %1").arg(Info.Code)); ui->textEdit->append(tr("Version : %1.%2.%3") .arg(QString::number(Info.V1)).arg(QString::number(Info.V2)).QString::number(Info.V3)); } } void MainWindow::CpuInfo() { TS7CpuInfo Info; int res=Client->GetCpuInfo(&Info); if (Check(res,"Unit Info")) { ui->textEdit->append(tr(" Module Type Name : %1").arg(Info.ModuleTypeName)); ui->textEdit->append(tr(" Serial Number : %1").arg(Info.SerialNumber)); ui->textEdit->append(tr(" AS Name : %1").arg(Info.ASName)); ui->textEdit->append(tr(" Module Name : %1").arg(Info.ModuleName)); } } void MainWindow::CpInfo() { TS7CpInfo Info; int res=Client->GetCpInfo(&Info); if (Check(res,"Communication processor Info")) { ui->textEdit->append(" Max PDU Length : " + QString::number(Info.MaxPduLengt) + " bytes"); ui->textEdit->append(" Max Connections : " + QString::number(Info.MaxConnections)); ui->textEdit->append(" Max MPI Rate : " + QString::number(Info.MaxMpiRate) + " bps"); ui->textEdit->append(" Max Bus Rate : " + QString::number(Info.MaxBusRate) + " bps"); }; } //------------------------------------------------------------------------------ // PLC Status //------------------------------------------------------------------------------ void MainWindow::UnitStatus() { int res=0; int Status=Client->PlcStatus(); if (Check(res,"CPU Status")) { switch (Status) { case S7CpuStatusRun : printf(" RUN\n"); break; case S7CpuStatusStop: printf(" STOP\n"); break; default : printf(" UNKNOWN\n"); break; } } } //------------------------------------------------------------------------------ // Upload DB0 (surely exists in AG) //------------------------------------------------------------------------------ void MainWindow::UploadDB0() { int Size = sizeof(Buffer); // Size is IN/OUT par // In input it tells the client the size available // In output it tells us how many bytes were uploaded. int res=Client->Upload(Block_SDB, 0, &Buffer, &Size); if (Check(res,"Block Upload (SDB 0)")) { ui->textEdit_2->append(tr("Dump (%1 bytes)").arg(Size)); //hexdump(&Buffer,Size); } } //------------------------------------------------------------------------------ // Async Upload DB0 (using callback as completion trigger) //------------------------------------------------------------------------------ void MainWindow::AsCBUploadDB0() { int Size = sizeof(Buffer); // Size is IN/OUT par // In input it tells the client the size available // In output it tells us how many bytes were uploaded. JobDone=false; int res=Client->AsUpload(Block_SDB, 0, &Buffer, &Size); if (res==0) { while (!JobDone) { SysSleep(100); } res=JobResult; } if (Check(res,"Async (callback) Block Upload (SDB 0)")) { ui->textEdit_2->append(tr("Dump (%1 bytes) : ").arg(QString::number(Size))); // hexdump(&Buffer,Size); } } void MainWindow::AsEWUploadDB0() { int Size = sizeof(Buffer); // Size is IN/OUT par // In input it tells the client the size available // In output it tells us how many bytes were uploaded. JobDone=false; int res=Client->AsUpload(Block_SDB, 0, &Buffer, &Size); if (res==0) { res=Client->WaitAsCompletion(3000); } if (Check(res,"Async (Wait event) Block Upload (SDB 0)")) { ui->textEdit_2->append(tr("Dump (%1 bytes) : ").arg(QString::number(Size))); // hexdump(&Buffer,Size); } } //------------------------------------------------------------------------------ // Async Upload DB0 (using polling as completion trigger) //------------------------------------------------------------------------------ void MainWindow::AsPOUploadDB0() { int Size = sizeof(Buffer); // Size is IN/OUT par // In input it tells the client the size available // In output it tells us how many bytes were uploaded. JobDone=false; int res=Client->AsUpload(Block_SDB, 0, &Buffer, &Size); if (res==0) { while (!Client->CheckAsCompletion(&res)) { SysSleep(100); }; } if (Check(res,"Async (polling) Block Upload (SDB 0)")) { ui->textEdit_2->append(tr("Dump (%1 bytes) : ").arg(Size)); // hexdump(&Buffer,Size); } } //------------------------------------------------------------------------------ // Read a sample SZL Block //------------------------------------------------------------------------------ void MainWindow::ReadSzl_0011_0000() { PS7SZL SZL = PS7SZL(&Buffer); // use our buffer casted as TS7SZL int Size = sizeof(Buffer); // Block ID 0x0011 IDX 0x0000 normally exists in every CPU int res=Client->ReadSZL(0x0011, 0x0000, SZL, &Size); if (Check(res,"Read SZL - ID : 0x0011, IDX 0x0000")) { ui->textEdit_2->append(tr(" LENTHDR : %1").arg(SZL->Header.LENTHDR)); ui->textEdit_2->append(tr(" N_DR : %1").arg(SZL->Header.N_DR)); ui->textEdit_2->append(tr("Dump (%1 bytes) ").arg(Size)); //hexdump(&Buffer,Size); } } //------------------------------------------------------------------------------ // Unit Connection //------------------------------------------------------------------------------ bool MainWindow::CliConnect() { int res = Client->ConnectTo(Address,Rack,Slot); if (Check(res,"UNIT Connection")) { ui->textEdit_2->append(tr(" Connected to : %1 (Rack= %2, Slot= %3)").arg(Address).arg(Rack).arg(Slot)); ui->textEdit_2->append(tr(" PDU Requested : %1 bytes").arg(Client->PDURequested())); ui->textEdit_2->append(tr(" PDU Negotiated : %1 bytes").arg(Client->PDULength())); }; return res==0; } //------------------------------------------------------------------------------ // Unit Disconnection //------------------------------------------------------------------------------ void MainWindow::CliDisconnect() { Client->Disconnect(); } //------------------------------------------------------------------------------ // Perform readonly tests, no cpu status modification //------------------------------------------------------------------------------ void MainWindow::PerformTests() { OrderCode(); CpuInfo(); CpInfo(); UnitStatus(); ReadSzl_0011_0000(); UploadDB0(); AsCBUploadDB0(); AsEWUploadDB0(); AsPOUploadDB0(); MultiRead(); } //------------------------------------------------------------------------------ // Tests Summary //------------------------------------------------------------------------------ void MainWindow::Summary() { ui->textEdit_2->append("+-----------------------------------------------------\n"); ui->textEdit_2->append("| Test Summary "); ui->textEdit_2->append("+-----------------------------------------------------\n"); ui->textEdit_2->append(tr("| Performed : %1").arg(ok+ko)); ui->textEdit_2->append(tr("| Passed : %1").arg(ok)); ui->textEdit_2->append(tr("| Failed : %1").arg(ko)); } /**********************************************************************************************/ #ifndef HEXDUMP_COLS #define HEXDUMP_COLS 16 #endif //void MainWindow::hexdump(void *mem, unsigned int len) //{ // unsigned int i, j; // for(i = 0; i < len + ((len % HEXDUMP_COLS) ? (HEXDUMP_COLS - len % HEXDUMP_COLS) : 0); i++) // { // /* print offset */ // if(i % HEXDUMP_COLS == 0) // { // u(ui->textEdit,"0x%04x: ", i); // ui->textEdit_2->setText(); // } // /* print hex data */ // if(i < len) // { // printf("%02x ", 0xFF & ((char*)mem)[i]); // } // else /* end of block, just aligning for ASCII dump */ // { // printf(" "); // } // /* print ASCII dump */ // if(i % HEXDUMP_COLS == (HEXDUMP_COLS - 1)) // { // for(j = i - (HEXDUMP_COLS - 1); j <= i; j++) // { // if(j >= len) /* end of block, not really printing */ // { // putchar(' '); // } // else if(isprint((((char*)mem)[j] & 0x7F))) /* printable char */ // { // putchar(0xFF & ((char*)mem)[j]); // } // else /* other char */ // { // putchar('.'); // } // } // putchar('\n'); // } // } //} MainWindow::~MainWindow() { delete ui; }
-
Which option are you currently using ?
Embedding the library or linking to it ?
If the later, did you compile it with the same compiler used for Qt ?
-
I didnt understan excatly what you mean.I wanna use link the .lib so that I will use just 3 files .h,.cpp,.lib but I suppose I have to use .dll as well in same file with .lib adding exectuble folder(I doesnt work,like you see Qt create a debug file and .exe after the compile )
-
Okay okay, when I create the this object in mainwindow.h ,this is being creating but I couldn't reach it from in mainwinbdow.cpp
into mainwindow.h
#ifndef MAINWINDOW_H #define MAINWINDOW_H #include <QMainWindow> #include "snap7.h" namespace Ui { class MainWindow; } class MainWindow : public QMainWindow { Q_OBJECT public: explicit MainWindow(QWidget *parent = 0); void CliCompletion(void *usrPtr, int opCode, int opResult); void SysSleep(uint32_t Delay_ms); bool Check(int Result, const char * function); void MultiRead(); void ListBlocks(); void OrderCode(); void CpuInfo(); void CpInfo(); void UnitStatus(); void UploadDB0(); void AsCBUploadDB0(); void AsEWUploadDB0(); void AsPOUploadDB0(); void ReadSzl_0011_0000(); bool CliConnect(); void CliDisconnect(); void PerformTests(); void Summary(); //void hexdump(void *mem, unsigned int len); ~MainWindow(); private: Ui::MainWindow *ui; TS7Client *Client = new TS7Client(); uint8_t Buffer[65536]; // 64 K buffer int SampleDBNum = 1000; char *Address = (char*)"192.168.0.1" ; // PLC IP Address int Rack=0,Slot=1; // Default Rack and Slot int ok = 0; // Number of test pass int ko = 0; // Number of test failure bool JobDone=false; int JobResult=0; }; #endif // MAINWINDOW_H
into .cpp```
//your code here
-
When I add the source files ,it worked properly.Also this lines is being added,I dont know why
win32:LIBS += C:\Qt\Tools\mingw530_32\i686-w64-mingw32\lib\libws2_32.a
win32:LIBS += C:\Qt\Tools\mingw530_32\i686-w64-mingw32\lib\libwinmm.a -
Hmm I have looked in Makefile and I encounter this line,
LIBS = -L"$(MINGW)/lib" -static-libgcc --no-export-all-symbols --add-stdcall-alias $(MINGW)/lib/libws2_32.a $(MINGW)/lib/libwinmm.a $(MINGW)/lib/gcc/mingw32/$(MINREL)/libstdc++.a
INCS = -I"$(MINGW)/include" -I"../../../src/sys" -I"../../../src/core" -I"../../../src/lib"Previously I realised , there is no files in mingw32 5.3.0 but libstdc++ is available
Also existing a this writing in webside, "Libstdc++ are statically linked, so you don’t need to distribute them with your software" I suppose it means that.
I do not have enough knowledge. -
Hmm I have looked in Makefile and I encounter this line,
LIBS = -L"$(MINGW)/lib" -static-libgcc --no-export-all-symbols --add-stdcall-alias $(MINGW)/lib/libws2_32.a $(MINGW)/lib/libwinmm.a $(MINGW)/lib/gcc/mingw32/$(MINREL)/libstdc++.a
INCS = -I"$(MINGW)/include" -I"../../../src/sys" -I"../../../src/core" -I"../../../src/lib"Previously I realised , there is no files in mingw32 5.3.0 but libstdc++ is available
Also existing a this writing in webside, "Libstdc++ are statically linked, so you don’t need to distribute them with your software" I suppose it means that.
I do not have enough knowledge.Hi
Statically linked means it is put inside and hence requires no DLL to
be included with the app.