ok i have main.cpp which loads functions from a dll
have another second.cpp
how do i use functions from main.cpp in second.cpp
or do i have to have main.cpp free the dll, and have second.cpp load the dll like main already did?
ok i have main.cpp which loads functions from a dll
have another second.cpp
how do i use functions from main.cpp in second.cpp
or do i have to have main.cpp free the dll, and have second.cpp load the dll like main already did?
There are some variations depending on your target system and build environment, but generally speaking.
1) Place declarations in a header file (say, main.h) of functions in main.cpp
2) #include "main.h" in second.cpp, preferably after #include'ing any standard header files.
3) Within second.cpp, call functions declared in main.h to your hearts content. Ensure you get types of function arguments, return types, and calling conventions right (note: if you have not specifically monkeyed with calling conventions, the only requirement to get calling conventions right is to use compatible compilers).
4) When building the executable, ensure the object files (main.o and second.o) are both included in the link. If usage of main.cpp requires use of a particular library, then also include that library in the link.
If your intent is to directly call functions in the DLL, then second.cpp needs to use the same technique as main.cpp does.
I've kept my answer generic - if you want a specific answer to your situation, you need to be specific in your question.
ok, just have the dll i am calling the functions in/from so no header
when i do the exact as main.cpp in the seond.cpp i get errors that they are already defined in main.obj.
basically i am using a vellman k8055 card, with its supplied dll
in main i have it loading the dll and taking the functions from it, like opencard();
but in the second.cpp (a dialog box) i need to use for example SetDigitalChannel();
how do i get second.cpp to use the function that main.cpp already "loaded"?
i am used to single source console programs, i am jumping into gui with multiple CPP and UI files in QT....
good news is i did manage to find out how to get dialog to send an int back to main!!!
That means you are duplicating function definitions (i.e. both source files implement a particular function). Remove the duplicates from one of your source files, recompile, and relink.
Beyond that, you will need to read the documentation that came with your card and DLL. Generally, it makes no difference how many object files call functions in a DLL - as long as the linker can resolve the calls (or, if you are dynamically loading the DLL, your program can resolve functions at run time - but, from what little you have described, you are not doing that).
well the functions are being called in main.cpp, and working, but i dont know how to call the functions in main.cpp FROM my second.cpp
Did you actually read my first post?
yeah
1 dont have a header, no idea how to make a header from a dll. although i would love to strip out a dll and just place the functions right into my program instead of using a dll
2 when i try to call everything in main and in second, i get duplication errors
other then that, no idea what to do.
You don't make a header file from a DLL, and you don't need to - and I never suggested you need to. If a header file is needed to use a DLL, they will be supplied together - and, to get main.cpp working with it, you would have used that already if needed.
You stated that you are seeking to call functions in main.cpp from second.cpp. To support that, you create - with your text editor or IDE, a header file with the appropriate function declarations (so the compiler has visibility of the function declarations when compiling both source files). Then you ensure that the functions are only implemented in one of the source files, not in both - if you don't do that, you get error messages about duplicated symbols from the linker. A function entry point is associated with a symbol. If you implement a function twice, the symbol is duplicated.
The fact that main.cpp is using the DLL is absolutely irrelevant.
The real problem is that you are just hacking together your main.cpp and second.cpp. They way you're doing it would get the same problem (duplicated symbols) even if you weren't using a DLL. It so happens main.cpp is using functions from a DLL, and you are assuming "oh, the problem is with the DLL, not the way I've hacked things".
well not hacking together, main.cpp is the main, second is the dialog box where you can "choose" an address for the connection to the card. trying to get the dialog to check if it can open the card, and if not warn the user, if so then open card and then close the dialog. Main will be doing all the functions, just need to pass the "opendevice" function to the dialog.
never said any prob was with the dll, just back to orig question, how do i call the function in main, from the second.cpp (the dialog).
making the declarations of the functions in a header sounds like it will work, and will try it asap.
thank you
That "orig question" is exactly what I answered in the second post of this thread. You're the one who kept associating things (in your opening posts, and subsequent replies) with the DLL, as if that was causing some other difficulty - at the same time as providing other information that indicated the DLL wasn't causing your problem.
Hoorah.
If main.cpp is implementing the "opendevice" function, then all that is needed is for the compiler to see a declaration of "opendevice" when compiling second.cpp. A header file providing said declaration is a common technique to achieve that.
If "opendevice" is a variable (say, a pointer to a function that main.cpp obtains from the dll) then the same answer applies. A declaration of "opendevice" in a header file, which is #include'd by both main.cpp and second.cpp, is sufficient.
In other words, the first post I made in this thread provided the answer.
ok made header
in main.cpp, before the main codeCode:intOpenDevice(intCardAddress); voidCloseDevice(); intSearchDevices(); intSetCurrentDevice(intlngCardAddress); intVersion(); intReadAnalogChannel(intChannel); voidReadAllAnalog(int*Data1,int*Data2); voidOutputAnalogChannel(intChannel,intData); voidOutputAllAnalog(intData1,intData2); voidClearAnalogChannel(intChannel); voidClearAllAnalog(); voidSetAnalogChannel(intChannel); voidSetAllAnalog(); voidWriteAllDigital(intData); voidClearDigitalChannel(intChannel); voidClearAllDigital(); voidSetDigitalChannel(intChannel); voidSetAllDigital(); boolReadDigitalChannel(intChannel); intReadAllDigital(); voidResetCounter(intCounterNr); intReadCounter(intCounterNr); voidSetCounterDebounceTime(intCounterNr,intDebounceTime); intReadBackDigitalOut(); voidReadBackAnalogOut(int*Buffer);
after mainCode:#include"relaypanel.h" #include"ui_relaypanel.h" #include<QApplication> #include<QtCore> #include<QtGui> #include<windows.h> #include"cardselect.h" #include"k8055.h" typedefvoid(CALLBACK*t_func)(int); typedefvoid(CALLBACK*t_func0)(); typedefint(CALLBACK*t_func1)(); typedefvoid(CALLBACK*t_func2)(int*,int*); typedefvoid(CALLBACK*t_func3)(int,int); typedefint(CALLBACK*t_func4)(int); typedefbool(CALLBACK*t_func5)(int); t_func4OpenDevice; t_func0CloseDevice; t_func0Version_; t_func4ReadAnalogChannel; t_func2ReadAllAnalog; t_func3OutputAnalogChannel; t_func3OutputAllAnalog; t_funcClearAnalogChannel; t_func0ClearAllAnalog; t_funcSetAnalogChannel; t_func0SetAllAnalog; t_funcWriteAllDigital; t_funcClearDigitalChannel; t_func0ClearAllDigital; t_funcSetDigitalChannel; t_func0SetAllDigital; t_func5ReadDigitalChannel; t_func1ReadAllDigital; intinit(void); HINSTANCEhDLL; inth=init();
in second.cppCode:intinit(void) { hDLL=LoadLibrary((LPCWSTR)L"k8055d"); if(hDLL!=NULL) { OpenDevice=(t_func4)GetProcAddress(hDLL,"OpenDevice"); if(!OpenDevice) {// handle the error FreeLibrary(hDLL); return-2; } CloseDevice=(t_func0)GetProcAddress(hDLL,"CloseDevice"); if(!CloseDevice) {// handle the error FreeLibrary(hDLL); return-2; } ReadAnalogChannel=(t_func4)GetProcAddress(hDLL,"ReadAnalogChannel"); if(!ReadAnalogChannel) {// handle the error FreeLibrary(hDLL); return-2; } ReadAllAnalog=(t_func2)GetProcAddress(hDLL,"ReadAllAnalog"); if(!ReadAllAnalog) {// handle the error FreeLibrary(hDLL); return-2; } OutputAnalogChannel=(t_func3)GetProcAddress(hDLL,"OutputAnalogChannel"); if(!OutputAnalogChannel) {// handle the error FreeLibrary(hDLL); return-2; } OutputAllAnalog=(t_func3)GetProcAddress(hDLL,"OutputAllAnalog"); if(!OutputAllAnalog) {// handle the error FreeLibrary(hDLL); return-2; } ClearAnalogChannel=(t_func)GetProcAddress(hDLL,"ClearAnalogChannel"); if(!ClearAnalogChannel) {// handle the error FreeLibrary(hDLL); return-2; } ClearAllAnalog=(t_func0)GetProcAddress(hDLL,"ClearAllAnalog"); if(!ClearAllAnalog) {// handle the error FreeLibrary(hDLL); return-2; } SetAnalogChannel=(t_func)GetProcAddress(hDLL,"SetAnalogChannel"); if(!SetAnalogChannel) {// handle the error FreeLibrary(hDLL); return-2; } SetAllAnalog=(t_func0)GetProcAddress(hDLL,"SetAllAnalog"); if(!SetAllAnalog) {// handle the error FreeLibrary(hDLL); return-2; } WriteAllDigital=(t_func)GetProcAddress(hDLL,"WriteAllDigital"); if(!WriteAllDigital) {// handle the error FreeLibrary(hDLL); return-2; } ClearDigitalChannel=(t_func)GetProcAddress(hDLL,"ClearDigitalChannel"); if(!ClearDigitalChannel) {// handle the error FreeLibrary(hDLL); return-2; } ClearAllDigital=(t_func0)GetProcAddress(hDLL,"ClearAllDigital"); if(!ClearAllDigital) {// handle the error FreeLibrary(hDLL); return-2; } SetDigitalChannel=(t_func)GetProcAddress(hDLL,"SetDigitalChannel"); if(!SetDigitalChannel) {// handle the error FreeLibrary(hDLL); return-2; } SetAllDigital=(t_func0)GetProcAddress(hDLL,"SetAllDigital"); if(!SetAllDigital) {// handle the error FreeLibrary(hDLL); return-2; } ReadDigitalChannel=(t_func5)GetProcAddress(hDLL,"ReadDigitalChannel"); if(!ReadDigitalChannel) {// handle the error FreeLibrary(hDLL); return-2; } ReadAllDigital=(t_func1)GetProcAddress(hDLL,"ReadAllDigital"); if(!ReadAllDigital) {// handle the error FreeLibrary(hDLL); return-2; } Version_=(t_func0)GetProcAddress(hDLL,"Version"); if(!Version_) {// handle the error FreeLibrary(hDLL); return-2; } return0;// ok } return-1;// error load DLL }
Code:#include"cardselect.h" #include"ui_cardselect.h" #include"k8055.h" #include<QtCore> #include<QtGui> intcard; CardSelect::CardSelect(QWidget*parent): QDialog(parent), ui(newUi::CardSelect) { ui->setupUi(this); } CardSelect::~CardSelect() { deleteui; } voidCardSelect::on_comboBox_highlighted(intindex) { card=index; } voidCardSelect::on_pushButton_clicked() { if(OpenDevice(card)==-1) QMessageBox::critical(0,"Failure","Card not attached or not set for address "+QString::number(card)); }
tons of errors,
alot of
error: C2365: 'OpenDevice' : redefinition; previous definition was 'function'
for each function
and all left operand because of functions.
either i missed something, or i have too much something! lol
ok tried making a header, and even included a header from the company.
still having probs.
my relaypanel (dialog, source and header) loads the dll, and functions of the dll, then calls cardselect (dialog, source and header)
how do i use a function, in this case opendevice, in the cardselect dialog.
tried declaring functions in header, and calling them from relaypanel, then including same header in cardselect, it doent know what the functions are OR screaming already declaired
"If your intent is to directly call functions in the DLL, then second.cpp needs to use the same technique as main.cpp does."
tried that and it screams duplicate also....
this all works as a single CPP, with a single UI, and also works as a single CPP in Console.
as soon as i add a dialog to do the card address selection, the functions dont carry over.
When writing in C++, take advantage of that. Every single one of those FreeLibrary calls can be eliminated by using RAII. Just create a little smart class and put FreeLibrary in the destructor.
My homepage
Advice: Take only as directed - If symptoms persist, please see your debugger
Linus Torvalds: "But it clearly is the only right way. The fact that everybody else does it some other way only means that they are wrong"
ok, i will start over with everything....
Created a new GUI Application with QT
selected DIALOG
default files made are
dialog.h
dialog.cppCode:#ifndef DIALOG_H #define DIALOG_H #include <QDialog> namespace Ui { class Dialog; } class Dialog : public QDialog { Q_OBJECT public: explicit Dialog(QWidget *parent = 0); ~Dialog(); private: Ui::Dialog *ui; }; #endif // DIALOG_H
main.cppCode:#include "dialog.h" #include "ui_dialog.h" Dialog::Dialog(QWidget *parent) : QDialog(parent), ui(new Ui::Dialog) { ui->setupUi(this); } Dialog::~Dialog() { delete ui; }
Code:#include "dialog.h" #include <QApplication> int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; w.show(); return a.exec(); }
now in my main.cpp, i add my dll loading files, and add dll to folder and use command to open the card at address 0
end up with main.cpp like this
Code:#include "dialog.h" #include <QApplication> #include <QtCore> #include <QtGui> #include <windows.h> typedef void(CALLBACK* t_func)(int ); typedef void(CALLBACK* t_func0)(); typedef int(CALLBACK* t_func1)(); typedef void(CALLBACK* t_func2)(int *, int *); typedef void(CALLBACK* t_func3)(int , int ); typedef int(CALLBACK* t_func4)(int ); typedef bool(CALLBACK* t_func5)(int ); t_func4 OpenDevice; t_func0 CloseDevice; t_func0 Version_; t_func4 ReadAnalogChannel; t_func2 ReadAllAnalog; t_func3 OutputAnalogChannel; t_func3 OutputAllAnalog; t_func ClearAnalogChannel; t_func0 ClearAllAnalog; t_func SetAnalogChannel; t_func0 SetAllAnalog; t_func WriteAllDigital; t_func ClearDigitalChannel; t_func0 ClearAllDigital; t_func SetDigitalChannel; t_func0 SetAllDigital; t_func5 ReadDigitalChannel; t_func1 ReadAllDigital; int init(void); HINSTANCE hDLL; int h = init(); int main(int argc, char *argv[]) { QApplication a(argc, argv); Dialog w; int foundDLL = 0; //Check if DLL was found and loaded// if (!h) { foundDLL = 1; } else { QMessageBox select; select.windowTitle()="Error"; select.critical(0, "Critical", "K8055D.DLL NOT FOUND\nExiting program"); ExitProcess(1); } //open card at address 0 // int Card = 0; if (foundDLL) { if(OpenDevice(Card) == -1) { QMessageBox::critical(0,"Failure!!!","Card not attached or not set for address "+QString::number(Card)); ExitProcess(9); // no card } if(OpenDevice(Card) != -1) QMessageBox::information(0,"Success!!!","Card attached on address "+QString::number(Card)); } w.show(); return a.exec(); CloseDevice(); FreeLibrary(hDLL); } int init(void) { hDLL = LoadLibrary((LPCWSTR)L"k8055d"); if (hDLL != NULL) { OpenDevice = (t_func4) GetProcAddress(hDLL, "OpenDevice"); if (!OpenDevice) { // handle the error FreeLibrary(hDLL); return -2; } CloseDevice = (t_func0) GetProcAddress(hDLL, "CloseDevice"); if (!CloseDevice) { // handle the error FreeLibrary(hDLL); return -2; } ReadAnalogChannel = (t_func4) GetProcAddress(hDLL, "ReadAnalogChannel"); if (!ReadAnalogChannel) { // handle the error FreeLibrary(hDLL); return -2; } ReadAllAnalog = (t_func2) GetProcAddress(hDLL, "ReadAllAnalog"); if (!ReadAllAnalog) { // handle the error FreeLibrary(hDLL); return -2; } OutputAnalogChannel = (t_func3) GetProcAddress(hDLL, "OutputAnalogChannel"); if (!OutputAnalogChannel) { // handle the error FreeLibrary(hDLL); return -2; } OutputAllAnalog = (t_func3) GetProcAddress(hDLL, "OutputAllAnalog"); if (!OutputAllAnalog) { // handle the error FreeLibrary(hDLL); return -2; } ClearAnalogChannel = (t_func) GetProcAddress(hDLL, "ClearAnalogChannel"); if (!ClearAnalogChannel) { // handle the error FreeLibrary(hDLL); return -2; } ClearAllAnalog = (t_func0) GetProcAddress(hDLL, "ClearAllAnalog"); if (!ClearAllAnalog) { // handle the error FreeLibrary(hDLL); return -2; } SetAnalogChannel = (t_func) GetProcAddress(hDLL, "SetAnalogChannel"); if (!SetAnalogChannel) { // handle the error FreeLibrary(hDLL); return -2; } SetAllAnalog = (t_func0) GetProcAddress(hDLL, "SetAllAnalog"); if (!SetAllAnalog) { // handle the error FreeLibrary(hDLL); return -2; } WriteAllDigital = (t_func) GetProcAddress(hDLL, "WriteAllDigital"); if (!WriteAllDigital) { // handle the error FreeLibrary(hDLL); return -2; } ClearDigitalChannel = (t_func) GetProcAddress(hDLL, "ClearDigitalChannel"); if (!ClearDigitalChannel) { // handle the error FreeLibrary(hDLL); return -2; } ClearAllDigital = (t_func0) GetProcAddress(hDLL, "ClearAllDigital"); if (!ClearAllDigital) { // handle the error FreeLibrary(hDLL); return -2; } SetDigitalChannel = (t_func) GetProcAddress(hDLL, "SetDigitalChannel"); if (!SetDigitalChannel) { // handle the error FreeLibrary(hDLL); return -2; } SetAllDigital = (t_func0) GetProcAddress(hDLL, "SetAllDigital"); if (!SetAllDigital) { // handle the error FreeLibrary(hDLL); return -2; } ReadDigitalChannel = (t_func5) GetProcAddress(hDLL, "ReadDigitalChannel"); if (!ReadDigitalChannel) { // handle the error FreeLibrary(hDLL); return -2; } ReadAllDigital = (t_func1) GetProcAddress(hDLL, "ReadAllDigital"); if (!ReadAllDigital) { // handle the error FreeLibrary(hDLL); return -2; } Version_ = (t_func0) GetProcAddress(hDLL, "Version"); if (!Version_) { // handle the error FreeLibrary(hDLL); return -2; } return 0; // ok } return -1; // error load DLL }
Then after run, this laods the dll, gets the functions, connects to the card, then opens the dialog..
NOW i want to control the card with dialog....
so in dialog.cpp how would i call the functions main.cpp loaded?
i just need to use lets say
to turn on relay 1, how would i call that function from the dialog.cpp?Code:SetDigitalChannel(1);
i hope this makes more sense, as it is NOT HACKED together, there is nothing wrong with the dll, nothing wrong with the program, as it runs fine from main.cpp, just need to use the function loaded form the dll at runtime in dialog...