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.
Related
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.
I have the problem with precompiled header. It looks somewhat like that
ftpch.h
#pragma once
#include <vector>
#include <iostream>
#include <string>
#include <Windows.h>
ftpch.cpp
#include "ftpch.h"
Then I have a header file and cpp in my dll library.
test.h
#pragma once
// DLL_EXPORT is a macro that changes for dll and console app like that:
// __declspec(dllexport) and __declspec(dllimport)
class DLL_EXPORT Test
{
std::string foo() {return "ara ara"};
}
And this code compiles fine when I compile my dynamic library project, but fails to compile when I include "test.h" in my console app project and try to compile it. The error I get is:
C2039: 'string' is not a member of 'std'
Your header files should always be self-sufficient. Include your libraries (in this case <string>) where you need them, everywhere you need them, and only where you need them.
If your header requires a certain library to function, include it in that file; don't reply on a different header to have included that library already, because if that different file changes, you're out of luck.
You've already got #include guards through #pragma once, so adding #include <string.h> to the header files that need it won't cause collision, and will also make them more maintainable and easy to interpret.
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
My objective is to create a dll and lib file so i'm following this guide
1) I created a new win32 Console Application project in VS, chose DLL as 'Application Type' and Emptied Project
2) I'm trying to create a database in C++. So I have 5 headers with ONLY function declarations.
3) Database.h is my top header, it looks like this:
#ifdef DBDLL_EXPORTS
#define DBDLL_API __declspec(dllexport)
#else
#define DBDLL_API __declspec(dllimport)
#endif
#ifndef __Database_H
#define __Database_H
#include "Table.h"
class DBDLL_API Database { ... };
#endif
4) Now with only headers, I tried compiling the project. It compiled but I don't see any DLLs or Libs anywhere in the project folder. How do I create them?
This is because headers are not compiled -- only CPP files are compiled (which pull in the headers -- a source file and all the headers it pulls in is called a "translation unit", which is the thing actually being compiled (independent of other TUs)).
So, in effect, the build system thinks you're building an empty project, and in this case generates nothing at all. Note that even if the headers are pulled in and compiled, unless an exported symbol is actually referenced somewhere, it may be optimized out. In such cases, you will get an (empty) DLL, but no .lib file (which can cause errors down the line if you have dependent projects looking for this .lib before there's anything in the DLL).
You'll need to create some CPP files that implement the functions declared in the headers. If you have everything in the headers and don't need any CPP files at all, then there's no point in having a DLL! (Since you could include the headers in any other project without needing any other dependency.)
Finally, your include guard (#ifndef ...) should encompass the entire header, including the DLL export macros, otherwise you'll eventually get macro redefinition warnings.
I would suggest using #pragma once instead of include guards since it's simpler and recognized by pretty much every compiler. I would also put the DLL macro goop into its own header (e.g. "dllmacros.h") and include that where it's needed (this will reduce duplication).
Is it possible to hide an
#include <header.h> //from library B
from projects using the library A?
I need to keep the include there because otherwise my library A won't compile, but as that header is from other library B that shouldn't be visible for the main project, the main program tries to find that header.h and compilation fails.
You could put it inside an #ifdef and define the symbol only when compiling library A:
#ifdef INCLUDE_FROM_LIBRARY_B
#include <header.h> //from library B
#endif //INCLUDE_FROM_LIBRARY_B
Update: but probably the best option is #Robinson's suggestion above: don't include it in any header file, only in .cpp files when needed.