How to use precompiled header with dynamic library and console application? - c++

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.

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.

VS2012 precompiled headers: how does my .h file know about includes in stdafx.h?

I have a very basic project in VS2012 using precompiled headers. I know that I'm supposed to add all "common" includes to stdafx.h and that I need to include this in each .cpp file. Thus, the basic setup looks like this:
Foo.h:
#ifndef FOO_H
#define FOO_H
class Foo {
public:
Foo();
~Foo();
void do(string str);
};
#endif
Foo.c:
#include "stdafx.h"
#include "Foo.h"
void Foo::do(string str) {}
in stdafx.h:
#include <string>
using namespace std;
Without precompiled headers, I'd put #include <string> into foo.h, since it has to know about the declaration of string. But how this foo.h know about string in this setup? (Note that stdafx.h is only included in the .cpp files).
Note: I have a working example that uses precompiled headers; the question is about how this works.
This is because the compiler processes headers in the order in which they appear in the main compilation unit.
Because the .cpp file included <string> (indirectly via "stdafx.h"), the contents of <string> are known to the compiler, and can be used by code that follows, even code pulled in from header files.
It is fragile though, because including your header file without first including <string> will cause errors.
You can look on the pre-compiled headers as a kind of cache for header files. The compiler analyzes a set of headers when it first encounters it (usually when compiling stdafx.cpp), compiles them, and then has the results ready for any module that needs them.

Under what conditions are C++ headers not transitive?

I've just run into a condition where I #include a header, I run into compilation errors that require me #including headers that were already included in the original header.
The header has the following contents:
#pragma once
#include <atlbase.h>
#include <atlcom.h>
#include "itestobj.h"
extern "C" ITestObj* WINAPI GetTestObj();
I then get a bunch of ATL-related compilation errors when I code against that which are resolved by including atlbase.h and atlcom.h in the C++ file in addition to the above header.
Why aren't these headers being included as would normally seem to be the case?
In all likelihood, at least one of these headers is including the file you show in your post. Since #pramga once tells your compiler to include it only once, it stops and you don't get all declarations.

How to check if MS compiler will compile my source code

Guys I was trying in VS to do something like:
#ifdef _MSC_VER
#include "stdafx.h"
#endif
but I'm getting an error telling me:
C1020: unexpected #endif
What is the correct way to do it?
Edit
/This is content of stdafx.h/
// stdafx.h : include file for standard system include files,
// or project specific include files that are used frequently, but
// are changed infrequently
//
#pragma once
#include "targetver.h"
//#include <stdio.h>
//#include <tchar.h>
#include <iostream>
using std::cout;
using std::cerr;
// TODO: reference additional headers your program requires here
You cannot put conditionals around stdafx.h because of the way MSVC precompiled headers work. It basically replaces everything once stdafx.h has been found (and usually requires #include "stdafx.h" to be the first line in the file) with the precompiled header contents, so it is as if you never wrote #if _MSC_VER and have an extra #endif.
Two solutions:
1) Do not use precompiled headers in your project. You can still use stdafx.h to include all the headers you require but compilation will be slow.
2) Put the conditional compile within the stdafx.h file.
(Taken from here)