I am currently trying to get my head around library linking with Qt in order to split up some existing code into logically structured modular parts that can be called by different applications.
I keep getting a problem where no obj files are being created... so I have created a smaller sample project and replicated my problem below.
It seems, to me, the problem lies in the library ...so I will start there.
If I have code like this, the obj file is created (and can therefore be linked to by my test application):
mylib.h
#ifndef MYLIB_H
#define MYLIB_H
#include "mylib_global.h"
class MYLIB_EXPORT MyLib
{
public:
MyLib();
~MyLib();
private:
};
#endif // MYLIB_H
mylib.cpp
#include "mylib.h"
MyLib::MyLib()
{
}
MyLib::~MyLib()
{
}
But if I remove the cpp file and just have the header file with function bodys included (as is the structure of my actual codes library as the code consists ONLY of templates), nothing is created:
mylib.h
// .......
public:
MyLib(){}
~MyLib(){}
// .......
How can I get Qt to build my code please?
If your library is just a header file, you don't need to compile it, include your headers in your other projects, and they will be compiled into it.
Related
I want to include a class from one project in another project.
I have a subdirs project that contains two sub projects, a windows qt console application and an autotest project to test the console application. My console application contains one class which I want to pull into my unit tests for testing:
Here's the header:
// calculator.h:
#ifndef CALCULATOR_H
#define CALCULATOR_H
class Calculator{
private:
public:
Calculator(int year);
int getYear(){ return 666; }
int getMonth();
int getDay();
};
#endif
Here's the source:
// calculate.cpp
"#include "calculator.h"
Calculator::Calculator(int year){}
int Calculator::getMonth(){
return 42;
}
int Calculator::getDay(){
return 3333;
}
Here's how my unit test looks:
//tst_foobar.cpp
#include <QtTest>
//#include "../Calculator/calculator.h"
#include "../Calculator/calculator.cpp"
// add necessary includes here
class Foobar : public QObject
{
Q_OBJECT
private slots:
void test_case1();
};
void Foobar::test_case1()
{
Calculator myCalc(42);
}
QTEST_APPLESS_MAIN(Foobar)
#include "tst_foobar.moc"
My problem is when I include the other subdir's header file like this: #include "../Calculator/calculator.h" it doesn't work properly. I cannot test any of the class functions defined in calculator.cpp. I can explicitly include calculate.cpp like this, #include "../Calculator/calculator.cpp" and my tests work as expected, but is this the proper way to do it?
I've never seen .cpp files included into files like this, only the header? But if only include the header, the header doesn't include the function definitions in calculator.cpp? Should my header file include the .cpp file? That way I could include just the header in other files like you often see in C++. By why then does the class generated by QT Creator do things the other way around? Creates a header file and a .cpp file, and the .cpp file is the one that includes the header??
Very new to C++ programming and a bit confused. Detailed help greatly appreciated.
Your questions are going to be answered as soon as you use CMake, so this might help.
All that boring part to find headers and cpp files are done within a CMakeLists.txt file. Then an executable file is created when you use add_executable()
Be aware that you will probably create a build directory to be "clean".
I think your CMakeLists.txt file is going to be something like
cmake_minimum_required(VERSION 2.8.11)
project(your_project_name)
enable_testing()
# Tell CMake to run moc when necessary:
set(CMAKE_AUTOMOC ON)
# As moc files are generated in the binary dir, tell CMake
# to always look for includes there:
set(CMAKE_INCLUDE_CURRENT_DIR ON)
find_package(Qt5Test REQUIRED)
add_executable(foo your_test.cpp your_src.cpp)
add_test(foo foo)
target_link_libraries(foo Qt5::Test)
You actually never include the cpp file.
If you include the h file you should be able to access the objects that are in the class.
When you include a .h file its basically saying copy whats in the .h file and paste it in the cpp. calculator.h is included in calculator.cpp so when the program compiles it will create binary file with both cpp and .h together. cpp files get compiled and linked together .h files dont since they are already going to be compiled with the .cpp. So in terms of main you just need to include the .h if you include .cpp it would not be efficient . **The reason why you also include the .h in main is so the program will know about the class. I hope that answers your question.
To sum things up: Include calculator.h in calculator.cpp and main.
I am writting a game, and at the same time building an engine for it and for other games I may make in the future. During testing on both the game logic and the engine (separately) run well. However when I try to link them together, I encountered some problem with the inclusion of header files.
To be specific, here is what I did:
The engine is built as Static Library (.lib), and depends on GLFW static library (glfw3.lib). It contains a Window.h file:
// Window.h
#pragma once
#include <glfw3.h> // include other library's header
#include <iostream>
//test if the linking success
void test() {
std::cout << "this is Window.h";
}
class Window
{
// Window class code (declaration, function prototype, etc...)
}
*Note that the location of GLFW library is separated from engine/game project location.
The game project is hosted under the same Solution with the engine project. In the game's Properties, I have add the engine as dependencies as well as engine's .lib and include location. Then I try the following:
// game's main file
#include <Window.h>
void main()
{
test(); // call the test function from Window.h
}
When building the game, I got an error says that it can not find such file called "glfw3.h". However, if I comment out the inclusion of glfw3.h in Window.h file:
# Window.h
#pragma once
//#include <glfw3.h>
then the game build and run normally, and prints out the test line in test function.
I want to build the engine as a single .lib with header files that prototypes functions for its classes; so that in the game project I only need to include/depend the engine library and no need to care about GLFW or such. How can I achive that?
I found a similar question, but it seems the answers don't solve my question.
You could try the suggestion from the related post below. Basically build your library as you are doing then statically merge it with the glfw static lib.
How to merge two windows vc static library into one
So I'm trying to create my own library in C++ and use it in another project.
So far it works with example code, but I have to include other libraries in my own library. So the problem is, that when I include the header files off my library,
the include paths in the header files are messed up.
A simple solution would be to add the search directories, but I don't think,
thats how its supposed to be resolved.
Sample Code - Library header file:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
int test();
The source file:
#include "sample.h"
int test() { return 20; }
Now the project in which I want to include the sample
#include <sample.h>
int main() { int a = test(); }
The problem is, that the include copies the code from sample.h directly into the main.cpp and the search directories for the other includes from sample.h are no longer defined
A simple solution would be to add the search directories, but I don't think, thats how its supposed to be resolved.
This is certainly the easiest solution since it requires no modifications to the code, and is usually an acceptable thing to do - however obviously it means the project can call the functions from glew.h and glfw3.h
The only alternative is to ensure the headers are not included by the library header, but instead by the source.
IE:
Library Header:
int test();
Library Source:
#include <GL/glew.h>
#include <GLFW/glfw3.h>
#include "sample.h"
int test() { return 20; }
And the project's source file left unchanged.
This requires that the types defined in glew.h and glfw3.h are not part of the public interface exposed by your library.
Eg, if your library had a function like:
GLFWwindow* window = openWindow(...);
You would need to change it to:
Library header:
struct WindowHandle;
WindowHandle* openWindow(...);
Library source:
struct WindowHandle{
GLFWwindow* window;
};
WindowHandle* openWindow(...){
WindowHandle* result;
//... do stuff...
result->window = //whatever;
return result;
}
This approach requires changing the library code, but has the advantage that the users of the library can't directly call the things the library depends on (glew and glfw in this case). This is particularly beneficial if you want to support multiple platforms, you could have a source file for opening windows via glfw, and another using direct x. The library's public interface would not need to be changed to support both backends.
If you want to know more about this approach try searching for "Opaque data types"
I created by the first time a dll to use with C++ (and then C#, I have plans to share this dll between a C++ and C# applications) using QT creator but when I try to use it I get SEGFAULT error.
Here's my files:
mydll.h
#ifndef MYDLL_H
#define MYDLL_H
#include "mydll_global.h"
class MYDLLSHARED_EXPORT MyDll
{
public:
MyDll();
int getAnswer();
};
MYDLLSHARED_EXPORT int getNumber();
#endif // MYDLL_H
mydll_global.h
#ifndef MYDLL_GLOBAL_H
#define MYDLL_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(MYDLL_LIBRARY)
# define MYDLLSHARED_EXPORT Q_DECL_EXPORT
#else
# define MYDLLSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // MYDLL_GLOBAL_H
mydll.cpp
#include "mydll.h"
MyDll::MyDll()
{
}
int MyDll::getAnswer()
{
return 42;
}
int getNumber()
{
return 10;
}
So I build it and created mydll.dll: then I went to other C++ project wheere I want to use this dll and put in the .pro file:
LIBS += "C:\path\to\mydll.h"
and in the main.cpp
#include "mydll.h"
and when I use function from dll like this:
qDebug() << getNumber();
I get a SEGFAULT error.
I thought that the header to provide the compiler type information and the dll to compiler to provide the function body was all I needed but as I'm getting a SEGFAULT I'm acessing NULL or someone else memory or so (I can't see the value on debug).
What am I missing?
First off, to link the DLL you need the link .lib file for that DLL. That file has all the binary manifest for linking.
Second, project file LIBS clause specify the list of .lib files to link with. Some of them may represent dynamic libraries (.dll).
See the example: Linking to Shared Library in Qt
Even better article covering both creation of DLL with Qt and using DLL in your Qt project: https://wiki.qt.io/How_to_create_a_library_with_Qt_and_use_it_in_an_application
I had this same issue. Almost every example I looked at had a class as their example, but I wanted to export functions like getNumber(). It's in the qt5 docs as you probably know by now.
This line needs to be in your header file:
extern "C" MYDLLSHARED_EXPORT int getNumber();
and it is either the mydll_global.h or mydll.h depending on what you are using.
mydll_global.h would be what qtcreator creates and puts export definitions in if you create a new Shared Library project.
I was thrown off guard by the extern "C" part as I wasn't using C and wasn't as familiar with how compilers export symbols.
Trying to add a public static function to a class definition using static MYDLLSHARED_EXPORT int getNumber(); or simply using a namespace (function defined with or without static) will give a not found for architecture x86_64 error using clang on osx.
EDIT: Forgive my noobish-ness, I haven't ever implemented a wrapper .dll before! :S
I've been tinkering a bit with some of the recently released Kinect Sensor hacks (namely OpenKinect and OpenNI) and I'm now trying to wrap the functionality in a *.dll for use in various "test" programs that I hope to write.
So far I've set up a *.dll project and have got a lot of the library functionality in, however I'm getting C4251 compiler warnings all over the place.
In the project settings I've got the OpenNI.lib file statically linked, so far my library header looks like this:
#ifdef LIBKINECT_EXPORTS
#define LIBKINECT_API __declspec(dllexport)
#else
#define LIBKINECT_API __declspec(dllimport)
#endif
// This class is exported from the LibKinect.dll
class LIBKINECT_API CLibKinect
{
public:
CLibKinect(void);
~CLibKinect(void);
bool Init(void);
protected:
private:
xn::Context m_xContext;
xn::DepthGenerator m_xDepthGen;
};
And my stdafx.h file contains:
#pragma once
#define WIN32_LEAN_AND_MEAN // Exclude rarely-used stuff from Windows headers
// Windows Header Files:
#include <windows.h>
#include <XnOpenNI.h>
#include <XnCodecIDs.h>
#include <XnCppWrapper.h>
Now I've attempted to create a windows console app to test the library and I get lots of error C2653: 'xn' : is not a class or namespace name errors. I was hoping that in the application I would only have to include and link to the wrapper *.dll not all of the OpenNI stuff as well, so as to hide the underlying implementation, is this incorrect?
Since you want to hide the fact you are using xn namespace in your implementation, you should not put that in the library header file. The simplest way to solve this problem is to use the pimpl idiom.