Re: How to use external source code in Qt creator?
Arcull, C++ isn't Basic. There is no such thing like "source code library" in C++. Either you include a source file in the project and the file get compiled and used to build your app or the file does not exist for the project at all. Period. Libraries exist in C++ only at the object file level: you must build the library first and then you can use it in subsequent projects. C++ is a compiled language.
Even if you succeed in specifying a directory where .cpp files are, all source files from that directory will be included in your project. That's something you surely do not want.
Re: How to use external source code in Qt creator?
Sorry I was away fro 2 days. Thanks for a detailed clarification Radek. Even if
Code:
SOURCES += ../elab/*.cpp
does work as expected, meaning it includes all cpp files to my qt app, I'll consider your good advice and include just the ones I need, let's say just mat.cpp in my case. Ok, with this, the experiment part of using uncompiled source code in my qt app is closed. I know how to and tested on example.
Now I would like to test the "lib" and "dll" option as well. I did try to open the "example" project from ChrisW67 in Qt creator. The "elab" project compiled to a dll ok, but I couldn't compile the "program", I got "undeclared refernce to precalc", meaning that the linker couldn't find the elab.dll. I double checked the folder containing the elab.dll was added to the system path enviromental variable, but still no go :( I alswo tried to append the to "elab.pro" file, rebuild it, still no go. Besides why doesn't the "Add library wizzard" allow me to select a "dll" folder, is it meant just for libs?
Ok, the same problem with "lib" option. I appended
Code:
CONFIG += staticlib
to "elab.pro" (removed config += dll) and built the lib. But I can't use it my program, same thing "undeclared refence to precalc". In the using lib option I could try also the "Add library wizzard" which automatically added some code in the pro file, but that didn't help either. Using "lib" shouldn't require to add lib folder to path enviromental varialbes, right? Can you please point out, what am I missing here. Thank you again for your help and patience :)
Re: How to use external source code in Qt creator?
(1) If precalc() is "undeclared" then the header mat.hpp is missing. The error comes from the compiler, not from the linker. Add mat.hpp to your project and also check the LIBS directive. It should be
Code:
LIBS += full_path/mat.lib
(2) In winblows, you cannot link with the dll directly. You need the import library as has been discussed above. You can link only with libraries (the .lib files). That's why the library wizard refuses to cooperate if you want him to add a .dll. The compiled dll project should contain mat.dll and mat.lib. Link with mat.lib. Check the LIBS directive, it should be the same as above.
Note on linux-ported things: In linux, the .lib files are the .a files, the dlls are the .so files. You can rename if you need.
Re: How to use external source code in Qt creator?
Ok, let's discuss the "lib" case please.
Quote:
If precalc() is "undeclared" then the header mat.hpp is missing. The error comes from the compiler, not from the linker.
sorry it was a typo, the error is
Code:
C:\Users\myuser\Documents\example\example\program\main.cpp:11: error: undefined reference to `precalc(int, int)'
so it is linking problem? In qt app I tried both
Code:
LIBS += -L"C:\Users\myuser\Documents\example\example\build-elab-Desktop_Qt_5_1_1_MSVC2010_32bit-Release\release" -lelab
LIBS += "C:\Users\myuser\Documents\example\example\build-elab-Desktop_Qt_5_1_1_MSVC2010_32bit-Release\release\elab.lib"
and I have
Code:
INCLUDEPATH += "C:\Users\myuser\Documents\example\example\elab"
where the mat.h is. Don't know what's missing here :(
Re: How to use external source code in Qt creator?
Then it is a linker complaint. The source code should be okay (providing mat.h is a part of your project). By mat.hpp I meant mat.h. Now:
(1) Does the (...)\release directory contain elab.lib?
(2) Does the elab lib contain precalc()? Use lib /list elab.lib for the check. You should see "precalc".
(3) Use the second form (simply "path/library.lib") of LIBS. The first form can cause problems. Do not use quotation marks around unless you absolutely must. Also, many software has troubles with blanks in file and directory names. Use rather names without blanks (it's not our case but an experience).
Re: How to use external source code in Qt creator?
Quote:
(1) Does the (...)\release directory contain elab.lib?
It does.
Quote:
(2)Does the elab lib contain precalc()? Use lib /list elab.lib for the check. You should see "precalc".
It probably doesnt. Running the lib /list elab.lib I get justSo I guess my elab.lib is not ok. How do I fix it in Qt? I open elab project in Qt designer and I have mat.h
Code:
#ifndef ADD_H
#define ADD_H
int precalc(int x, int y);
#endif
mat.cpp
Code:
int precalc(int x, int y) {
return (x + y);
}
and elab.pro
Code:
TEMPLATE = lib
CONFIG += staticlib
TARGET = elab
QT -= core
HEADERS = mat.h
SOURCES = mat.cpp
Shouldn't this build a valid "lib"?
Quote:
(3) Use the second form (simply "path/library.lib") of LIBS. The first form can cause problems. Do not use quotation marks around unless you absolutely must. Also, many software has troubles with blanks in file and directory names. Use rather names without blanks (it's not our case but an experience).
Ok I used the second form, no spaces in path, but I don't think this is the problem.
Re: How to use external source code in Qt creator?
Ok, I made some progress in using "elab" project as a static lib library.
Quote:
(2)Does the elab lib contain precalc()? Use lib /list elab.lib for the check. You should see "precalc".
It probably doesnt. Running the lib /list elab.lib I get just
It does, lib.exe doesn't show public symbols in library, you need to run
Code:
dumpbin.exe /all elab.lib
to get more info. By the way both tools are in included in MS Visual Studio installation.
So I went on and tried to compile both (elab and program project) targetting different platforms (mingw, msvc2010,...) and found out that if I build the "elab" with mingw, I get a "libelab.a" file, which I can use in "program" compiled with mingw, while all other combinations (mingw-elab & msvc2010-program,msvc2010-elab & msvc2010-program,msvc2010-elab & mingw-program) do not work. So the actuall problem is not the code of "elab" and "program" but the convetions of calling external libraries. These depend on the compiler/linker, they obviously used some default values in my cases, but googling a bit revealed you can request them somehow. I tried using something like this in my "elab":
Code:
int __stdcall precalc(int x, int y);
and
Code:
int __cdecl precalc(int x, int y);
in declaration and implementation part of my function, but still no luck. I guess I should give some additional directives to compiler, but don't know how yet. So maybe someone with deeper knowledge in "cross compiling" could explain how to do it properly in somple words.
Meanwhile I'll try to build an example of using "elab" as a dynamic link library. Thank your for your help so far. Best regards.
Re: How to use external source code in Qt creator?
Hi, it's time to revive this thread :) It took me a while to figure out all the missing puzzles and get the things working. So I went and prepared "all"(the ones I know) possible scenarios of external code usage (source code, static linking, dynamic linking with import libraries, dynamic linking with public symbols), in case someone will find it usefull. Bellow are listed the important files of working examples. PS: I renamed previos names of functions to avoid confusion.
- source code
elab.pro
Code:
TEMPLATE = lib
TARGET = elab
QT -= core
HEADERS = mat.h
SOURCES = mat.cpp
mat.h
Code:
#ifndef ADD_H
#define ADD_H
class elabclass {
public:
int sumints(int x, int y);
};
int multipyints(int x, int y);
#endif
mat.cpp
Code:
#include "mat.h"
int elabclass::sumints(int x, int y) {
return (x + y);
}
int multipyints(int x, int y) {
return (x *y);
}
program.pro
Code:
TEMPLATE = app
TARGET = program
INCLUDEPATH += "C:\Users\myuser\Documents\example_source\example\elab"
SOURCES += "C:\Users\myuser\Documents\example_source\example\elab\mat.cpp" main.cpp
main.cpp
Code:
#include <iostream>
#include "mat.h"
int sumup(int a, int b) {
return (a + b);
}
int main() {
using namespace std;
int a,b,c;
a = b = c = 0;
elabclass myelab;
a = myelab.sumints(3,4);
cout << "sum of 3 and 4 is " << a << endl;
b = multipyints(2,5);
cout << "2 times 5 is " << b << endl;
c = sumup(6,2);
cout << "sum of 6 and 2 is " << c;
return 0;
}
- static linking
elab.pro
Code:
TEMPLATE = lib
CONFIG += staticlib
TARGET = elab
QT -= core
HEADERS = mat.h
SOURCES = mat.cpp
mat.h
Code:
#ifndef ADD_H
#define ADD_H
//int __cdecl precalc(int x, int y);
class elabclass {
public:
int sumints(int x, int y);
};
int multiplyints(int x, int y);
#endif
mat.cpp
Code:
#include "mat.h"
int elabclass::sumints(int x,int y) {
return (x + y);
}
int multiplyints(int x, int y) {
return (x * y);
}
program.pro
Code:
TEMPLATE = app
TARGET = program
# So that the compiler will find the mat.h file
INCLUDEPATH += "C:\Users\myuser\Documents\example_static\example\elab"
# So that the linker will filnd the link library
LIBS += "C:\Users\myuser\Documents\example_static\example\build-elab-Desktop_Qt_5_1_1_MinGW_32bit-Release\release\libelab.a"
//LIBS += "C:\Users\myuser\Documents\example_static\example\build-elab-Desktop_Qt_5_1_1_MSVC2010_32bit-Release\release\elab.lib"
SOURCES += \
main.cpp
main.cpp
Code:
#include <iostream>
#include "mat.h"
int sumup(int a, int b) {
return (a + b);
}
int main() {
using namespace std;
int a,b,c;
a = b = c = 0;
elabclass myelab;
a = myelab.sumints(3,4);
cout << "sum of 3 and 4 is " << a << endl;
b = multiplyints(2,5);
cout << "2 times 5 is " << b << endl;
c = sumup(6,2);
cout << "The sum of 6 and 2 is " << c << endl;
printf("end of program");
return 0;
}
- dynamic linking with import libs
elab.pro
Code:
TEMPLATE = lib
CONFIG += dll
TARGET = elab
QT -= core
HEADERS = mat.h \
elab_global.h
SOURCES = mat.cpp
DEFINES += ELAB
mat.h
Code:
#ifndef MAT
#define MAT
#include "elab_global.h";
class ELAB_SPEC elabclass {
public:
int sumints(int x, int y);
};
ELAB_SPEC int multiplyints(int x, int y);
#endif // MAT_H
mat.cpp
Code:
#include "mat.h"
int elabclass:: sumints (int x, int y) {
return (x + y);
}
int multiplyints (int x, int y) {
return(x * y);
}
program.pro
Code:
TEMPLATE = app
TARGET = program
SOURCES += main.cpp
INCLUDEPATH += "C:\Users\myuser\Documents\example_dynamic_import-libs\example\elab"
//LIBS += "C:\Users\myuser\Documents\example_dynamic_import-libs\example\build-elab-Desktop_Qt_5_1_1_MSVC2010_32bit-Release\release\elab.lib"
LIBS += "C:\Users\myuser\Documents\example_dynamic_import-libs\example\build-elab-Desktop_Qt_5_1_1_MinGW_32bit-Release\release\libelab.a"
main.cpp
Code:
#include <iostream>
#include <QLibrary>
#include <QtDebug>
#include "elab_global.h"
#include "mat.h"
int sumup(int a, int b) {
return (a + b);
}
int main() {
using namespace std;
int a,b,c;
a = b = c =0;
elabclass myelab;
a = myelab.sumints(3,4);
cout << "sum of 3 and 4 is " << a << endl;
b = multiplyints(2,5);
cout << "2 times 5 is " << b << endl;
c = sumup(6,2);
cout << "sum of 6 and 2 is " << c << endl;
return 0;
}
- dynamic linking with public symbols
elab.pro
Code:
TEMPLATE = lib
CONFIG += dll
TARGET = elab
QT -= core
HEADERS = mat.h \
elab_global.h
SOURCES = mat.cpp
DEFINES += ELAB
mat.h
Code:
#ifndef MAT
#define MAT
#include "elab_global.h";
class ELAB_SPEC elabclass {
public:
elabclass();
int sumints(int x, int y);
};
extern "C" {
ELAB_SPEC int multiplyints(int x, int y);
}
#endif
mat.cpp
Code:
#include "mat.h"
extern "C" __declspec(dllexport) int sumints(int x, int y) {
return (x + y);
}
extern "C" __declspec(dllexport) int multiplyints (int x, int y) {
return(x * y);
}
program.pro
Code:
TEMPLATE = app
TARGET = program
SOURCES += main.cpp
main.cpp
Code:
#include <iostream>
#include <QLibrary>
#include <QtDebug>
int sumup(int a, int b) {
return (a + b);
}
int main() {
using namespace std;
int a = 0;
if (!library.load()) {
cout << "failed to load elab.dll" << endl;
} else {
cout << "elab.dll loaded ok" << endl;
typedef int (*sumintsprototype)(int,int);
sumintsprototype sumcalc = (sumintsprototype) library.resolve("sumints");
if (sumcalc)
a = sumcalc(3,4);
if (sumcalc == 0 || a == 0){
qDebug() << library.errorString();
qDebug() << "Cant run the sumints in elab.dll";
} else {
cout << "sum of 3 and 4 is " << a << endl;
}
typedef int (*multipLyintsprototype)(int,int);
multipLyintsprototype multycalc = (multipLyintsprototype) library.resolve("multiplyints");
if (multycalc)
a = multycalc(2,5);
if (multycalc == 0 || a == 0){
qDebug() << library.errorString() << endl;
qDebug() << "Cant run the multiplyints in elab.dll" <<endl ;
} else {
cout << "2 times 5 is " << a << endl;
}
library.unload();
}
int c = sumup(6,2);
cout << "sum of 6 and 2 is " << c << endl;
return 0;
}