Export all functions in imported header files - c++

I am building a dll file using cmake and c++ on windows. My project is composed of several header files, and one complete header file to be included in a different c++ project. The larger header file looks something like the following:
#include "header1.h"
#include "header2.h"
#include "header3.h"
...
I read that I have to use __declspec(dllimport) and __declspec(dllexport), so I have used some ifdef statements like this:
#ifdef _WIN32
# ifdef EXPORT
# define API __declspec(dllexport)
# else
# define API __declspec(dllimport)
# endif
#elif
# define API
#endif
My questions is: do I have to put this in every header file, or can I somehow do it for the header file as a whole? For example, like this:
#include API "header1.h"
#include API "header2.h"
#include API "header3.h"
...
(does not work, but is there something similar to this that does?)

There is no way to avoid this boilerplate. Most project simply put common code which defines the API-like macro to a dedicated header and #include it at start of each public header file.

Related

How to export multiple header files as a single header file in C++?

I'm developing a DLL using Visual Studio. Currently, I have one header file: MyProject.h:
#pragma once
#ifdef MYLIBRARY_EXPORTS
#define MYLIBRARY_API __declspec(dllexport)
#else
#define MYLIBRARY_API __declspec(dllimport)
#endif
#include <map>
#include <string>
extern "C" class MYLIBRARY_API Class1
{
// some stuff here...
};
extern "C" class MYLIBRARY_API Class2
{
// some stuff here
};
I am going to be adding some more classes to the project and I would like to add separate header files for each class (please advise if I should not do that). However, eventually, I want to package all that into a single .dll and .lib in such a way that the client only needs to include a single header file. That is, the client project has #include "MyProject.h" which is essentially a collection of header files with their implmentation files. Is this possible and how can I achieve this? Thanks.
EDIT:
To be specific, what I want to do is to put Class1 in Class1.h and Class2 in Class2.h and include both of them in one master header file called MyLibrary.h so that a client only have to do #include "MyLibrary.h".
If you have several header files like A.h, B.h etc and want to give the client just Project.h that includes all, then simply include all the headers in Project.h - like so:
#ifndef MY_PROJECT_H
#define MY_PROJECT_H
#include "A.h"
#include "B.h"
#endif
Sorry ,I misunderstood what you were asking.
Yes, you can have multiple header-files that are included in your library header-file (be sure to include them with #include "...").
if you want to eliminate the need of specifying library in the linker-section (this is what I thought you were asking) ,with MSVC++ the thing you're looking for is
#pragma comment( comment-type [,"commentstring"] )
https://learn.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp

C++ DLL Header includes

I am creating a DLL inside Visual Studio.
I have 3 own header files that I includes in the header file of the DLL.
I want to throw away the 3 header files once they are compiled inside the DLL.
I tried many ways to accomplish this but not with good results. When I remove the 3 header files from the project, I get errors that the header files are missing. The DLL is compiled and created.
DLL.h :
#ifndef DLL_H
#define DLL_H
#include "header1.h"
#include "header2.h"
#include "header3.h"
#endif
I included the DLL.h in my main.cpp to use the DLL and the header files that are included.
I also created a DLL.cpp but this file is empty.
How do I set up the files or settings inside Visual Studio that the header files can be recognized from the DLL but that the header files are not present?
If these headers are not relevant to API exported by DLL you shouldn't include them in DLL header file.
If you really want to do it such way you you can hide them with preprocessor.
#ifndef DLL_H
#define DLL_H
// You can set BUILDING_DLL=1 in only DLL project,
// I assume that you already have such variable to determine
// whenever to use __declspec(dllexport) or __declspec(dllimport)
#if BUILDING_DLL
#include "header1.h"
#include "header2.h"
#include "header3.h"
#endif
#endif
But I encourage you to verify if it is needed. Will it compile without these headers? If it will you can simply remove them and include only in cpp file. If it will not, you cannot remove them since once you will want to link to DLL compiler must know API and ABI coming from this header. E.g. if there is declared some type that is used as function argument compiler must know this type.

C++ parameterized header inclusion

I'm working on an image processing project, and have created many libraries for different feature extraction methods. I have also another library that uses one of these libraries.
I don't want to include all of them, so I would like to selectively include libraries based on parameters defined by a config file. The config file stores the parameter and its value as shown below:
lib: "a"
Is it possible to selectively include "library a" by reading the parameters in from this config file?
You can include conditionals in compilation time with #ifdef #ifndef #endif directives
#define TypeA
#define TypeB
#ifdef TypeA
#include <lib.h>
#endif
#ifdef TypeB
#include <stdio.h>
#endif

Compile dll in Qt with VS compiler to use it in Borland

I have a package of C functions and I need to create DLL library from it, that can be used in C++ program. I haven't done any library before, so I am total beginner in that. I am working in Qt Creator.
My first try was to create it according to the manual Creating shared libraries, so I added these two lines to my project file:
TEMPLATE = lib
DEFINES += MYLIB_LIBRARY
Then I created mylib.h file
#ifndef MYLIB_H
#define MYLIB_H
#include "mylib_global.h"
#include "functions1.h"
#include "functions2.h"
#include "functions3.h"
class MYLIBSHARED_EXPORT Mylib
{
public:
Mylib(){};
};
#endif // MYLIB_H
Finally I added mylib_global.h:
#ifndef MYLIB_GLOBAL_H
#define MYLIB_GLOBAL_H
#include <QtCore/qglobal.h>
#if defined(MYLIB_LIBRARY)
# define MYLIBSHARED_EXPORT Q_DECL_EXPORT
#else
# define MYLIBSHARED_EXPORT Q_DECL_IMPORT
#endif
#endif // MYLIB_GLOBAL_H
To make functions usable in C++ I used these lines for each function in library
#ifdef __cplusplus
extern "C"{
#endif
void foo();
#ifdef __cplusplus
}
#endif
When compiling with MSVC2012 everything seems ok and I got some .dll file. But then I sent library to someone, who wanted to use it in Borland C++. He told me that I have to compile it with some DEF file to tell to VS compiler right names and with __stdcall instead of __cdecl. But I have no idea how to do it in Qt. Any explanation and help would be really appreciated. Thanks
P.S. I looked at posts Using VS dll in old Borland and Import VS dll in C Builder, but they
did not help me to understand the problem.
If you want to export the foo function, you need to tell the linker somehow.
What you were suggested is to use a .def file, which is quite easy.
Just create a file like exports.def in your project directory, and write in it something like:
EXPORTS
foo
Then go to your library project settings -> Linker -> Input -> Module Definition File
and fill in your .def file name

How can I use the #error directive to provide the user pointers to useful information?

Suppose I have a file like the following
Mainfile.cpp
#include "stdafx.h"
#include <stdlib.h>
#include "Myfile.h"
#ifdef _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif
int _tmain(int argc, _TCHAR* argv[])
{
system("pause");
return 0;
}
Myfile.h
#pragma once
#undef _MYFILE
#define MYFILE
My goal is to provide additional information ("Please refer to ....") in case something is missing (MyFile.h was not included/found on the path).
How can I handle this with a third party library, like Boost? In this case, I don't have control on Boost and I cannot handle the definition of _MYFILE: then how can throw the error?
Pseudo code
#include "boost/boost.h"
#if (boost is not included || directory path is not set || boost .h file not found)
#error: Set boost path and compile again
#endif
It is impossible to do what you want in C/C++ code. Once you enter #include "myfile.h" it is up to compiler to locate that file and throw an error if it's nowhere to be found.
You are also misusing #ifndef ... #error ... #endif.
Some people use it to track header dependencies; imagine you have a header messages.h which requires header mytypes.h. Usually you just write something like this:
// File mytypes.h
#ifndef MYTYPES_H
#define MYTYPES_H
typedef unsigned char UINT8;
// ...
#endif
// File messages.h
#ifndef MESSAGES_H
#define MESSAGES_H
#include "mytypes.h"
// ...
#endif
But you can also write messages.h like that:
#ifndef MESSAGES_H
#define MESSAGES_H
#ifndef MYTYPES_H
#error I need mytypes.h to compile!
#endif
#endif
but it quickly becomes a chore to insert #errors for all the headers you depend on and then include those dependencies over and over again in all the source files where your header is needed. So in most cases first approach is the way to go.
You also need to decide what type of include guard you want to use. Don't #define MYFILE if you're already using #pragma once. Choose one and stick to it. (and remember that #pragma once is nonstandard).
Finally last but not least: if you really need to be that user friendly you will need to use your build system to verify that all extra libraries are installed and their headers are available. My guess is you're using Visual Studio's native builder. I don't know that one but I read it has pre-build actions so perhaps it's possible to define one which verifies boost location via some native visual studio calls or simply by running a batch file included in the project.
Shouldn't
#if _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif
be
#ifndef _MYFILE
#error Myfile.h to be included. Please refer Ream Me at C:\ReadMe
#endif