How to avoid repeated execution of loading Qlibrary?
-
@jsulm said in How to avoid repeated execution of loading Qlibrary?:
reinterpret_cast<Fn6>(myLib.resolve("DEVICE_StartMeasurement"));
I moved "reinterpret_cast<Fn6>(myLib.resolve("DEVICE_StartMeasurement"));" in the constructor, so all I have in mainwindow.h is this :
class MainWindow : public QMainWindow { Q_OBJECT QLibrary myLib(); typedef DEVICE_ERROR_TYPES(__stdcall* Fn6)(void); public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); ...
And in the "Constructor", I have this code :
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) // Constructor , ui(new Ui::MainWindow) { ui->setupUi(this); QLibrary myLib("FDXSDK.dll"); bool Result; Result = myLib.load(); Fn6 RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement")); }
Then, in the Measure button, I end up with this code :
void MainWindow::on_btnMeasure_clicked() { sdkError = RB_StartMeasurement();
For which I get :
use of undeclared identifier 'RB_Startmeasurement'...
Lost again... Maybe that reference to 'initialize with a null pointer' I'm missing?
-
Fn6 RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement"));
This declares
RB_StartMeasurement
as a local variable in methodMainWindow::MainWindow()
. That means you won't be able to access it another method, likeMainWindow::on_btnMeasure_clicked()
, as you're seeing from theundeclared identifier
message.You want
Fn6 RB_StartMeasurement
to be a member variable of theMainWindow
class, declared in the.h
file. Then you assign it as you have done inMainWindow::MainWindow
but without that type declaration in front of it, as:RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement")); // equivalent to this->RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement"));
Now you can access
RB_StartMeasurement()
/this->RB_StartMeasurement()
in otherMainWindow
methods, like you tried. -
Thank you all for your patience and help...
So, I made "Fn6 RB_StartMeasurement" a member variable of the MainWindow class, declared in the .h file, like this :
class MainWindow : public QMainWindow { Q_OBJECT // Macro Meta Object Compiler QLibrary myLib(); typedef DEVICE_ERROR_TYPES(__stdcall* Fn6)(void); Fn6 RB_StartMeasurement(); public: MainWindow(QWidget *parent = nullptr); ~MainWindow(); ...
Then in MainWindow::MainWindow, I assign it, without the type declaration in front of it, like this :
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) , ui(new Ui::MainWindow) { ui->setupUi(this); QLibrary myLib("DEVICE.dll"); bool Result; Result = myLib.load(); RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("DEVICE_StartMeasurement")); }
But that gives me :
reference to non-static member function must be called...
I must still be missing something...
-
@RogerBreton said in How to avoid repeated execution of loading Qlibrary?:
Fn6 RB_StartMeasurement();
You want a function pointer variable, as you had originally, i.e.
Fn6 RB_StartMeasurement;
not a function call, with the round parentheses after it.
-
@RogerBreton said in How to avoid repeated execution of loading Qlibrary?:
QLibrary myLib("DEVICE.dll");
Why do you declare another myLib inside constructor?! Use the class instance myLib.
-
I fixed the header this way :
class MainWindow : public QMainWindow { Q_OBJECT // Macro Meta Object Compiler QLibrary myLib(); typedef DEVICE_ERROR_TYPES(__stdcall* Fn6)(void); Fn6 RB_StartMeasurement; ...
But then, in the Constructor, I have this code :
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) // Constructor , ui(new Ui::MainWindow) { ui->setupUi(this); bool Result; Result = myLib.load("DEVICE.dll"); RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement")); } ...
Notice how, this time, I use the myLib class instance? But I must not have the correct logic because the compiler says :
reference to non-static member function must be called
Same error for the RB_StartMeasurement :(
Boy! Thank you guys for your patience!
-
@RogerBreton said in How to avoid repeated execution of loading Qlibrary?:
Notice how, this time, I use the myLib class instance? But I must not have the correct logic because the compiler says :
reference to non-static member function must be called
You have
QLibrary myLib();
. You like those()
parentheses, don't you? ;-) You are going to callmyLib.load("DEVICE.dll")
. Don't you think your declaration should beQLibrary myLib;
instead? -
I notice, afterwards, that the declaration should not have parentheses :
class MainWindow : public QMainWindow { Q_OBJECT QLibrary myLib; typedef FDXSDK_ERROR_TYPES(__stdcall* Fn6)(void); Fn6 RB_StartMeasurement; ...
But then, in the constuctor, I could not understand why I was still the error "Too many arguments to function call" when I tried to pass the name of the DLL to the load library function:
MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent) // Constructor , ui(new Ui::MainWindow) { ui->setupUi(this); bool Result; Result = myLib.load("DEVICE.dll"); RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement")); }
It's one thing to declare myLib as of type Qlibrary in the header but I don't understand, why in the implementation, the compiler would complain?
jsum commented earlier :Why do you declare another myLib inside constructor?! Use the class instance myLib.
So I think, that is what I'm doing, using the class instance myLib.
Unless I leave the call to Load without arguments, like this :bool Result; Result = myLib.load();
But this does not seem to make sense?
The documentation states:
The resolve() function implicitly tries to load the library if it has not been loaded yet.
But where will it gets the name of the DLL to load in memory, if it is never specified in the first place?Take the Measure button code :
void MainWindow::on_btnMeasure_clicked() { sdkError = RB_StartMeasurement();
Where is the application going to get the DLL from?
-
@RogerBreton said in How to avoid repeated execution of loading Qlibrary?:
But where will it gets the name of the DLL to load in memory, if it is never specified in the first place?
Via the ctor
I was still the error "Too many arguments to function call" when I tried to pass the name of the DLL to the load library function:
Because you declared a class function named
myLib()
which returns a QLibrary object. -
I wanted to try the changes in debug mode but I immediately ran into the following error message :
Time for a cup of coffee...
-
@RogerBreton said in How to avoid repeated execution of loading Qlibrary?:
Time for a cup of coffee...
I would rather say - time for a debugging session :)
-
@RogerBreton
If, from what you have shown, you presently have:bool Result; Result = myLib.load(); RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement")); sdkError = RB_StartMeasurement();
without checking the intermediate return result variables,
RB_StartMeasurement
may benullptr
. ThenRB_StartMeasurement()
would cause aSIGSEGV
? -
@JonB I don't dare say RB_StartMeasurement may be a nullptr in ALL LIKELIHOOD, and that maybe the cause of the segmentation fault. That is exactly my hypothesis. So, if that is the case, this proves my intuition : where is the application getting the DLL from? If its name isn't specified anywhere? It is not in the PRO file.
I was thinking, perhaps, I should test whether the library is loaded before calling RB_StartMeasurement? And if it is not loaded, then load it? But that would not explain why I get the SIGSEV when the application tries to load? Or is it happening in the constructor?
Somehow, I must be missing some important piece of the puzzle -- I'll continue to look around but I am optimistic...
-
bool Result; Result = myLib.load(); if (!Result) qDebug() << "This is bad..."; RB_StartMeasurement = reinterpret_cast<Fn6>(myLib.resolve("FDX_StartMeasurement")); if (RB_StartMeasurement == nullptr) qDebug() << "This is bad. Get ready for SEGV if you call RB_StartMeasurement() now..."; sdkError = RB_StartMeasurement();
-
I declared the RB_StartMeasurement as NULL in mainwindow.h :
class MainWindow : public QMainWindow { Q_OBJECT QLibrary myLib; typedef DEVICE_ERROR_TYPES(__stdcall* Fn6)(void); Fn6 RB_StartMeasurement = NULL;
But I still get the Segmentation Fault...
-
@SGaist That is exactly what I do :
I found the culprit...
DEVICE_ERROR_TYPES sdkError = RB_RegisterDeviceEventHandler(EventNotice);
The above function is a static member function declared in SomeClassName... which was working fine before ... The EventNotice function is also part of the same class.
-
For some reason (?), the EventNotice "address" is garbage :
EventNotice 2372415452829272149 void (DEVICE_eEventCode, uint32_km, DEVICE_ERROR_TYPES)
It should be a proper address like 0x00007ff739a21970.
I tried restarting QT Creator many times to no avail. -
Thank you all for your patient help.
I'm putting QT on the backburner for now.
Too bad. Such a nice environment.