1
votes

I am in need of some advice on how to setup my project. I'm building a static library and want to know if the way I'm using precompiled headers is correct before I go too far.

So far, my stdafx file is just including (for types like DWORD, etc.) and (for std::string).

I built a simple cpp/header combo called TestFuncs.cpp/h

TestFuncs.cpp:

#include "stdafx.h"
using namespace std;
void MyFunc(DWORD a, string b) {
    // irrelevant
}

TestFuncs.h

#pragma once
void MyFunc(DWORD a, std::string b);

This code here compiles properly. The issue that I have is when I want to use this static library in another project, I would normally do #include "path_to_my_static_lib_project/TestFuncs.h"

However, the issue with this, is based upon TestFuncs.h, both DWORD and string would be unknown at the time, as they are types defined from the stdafx.h file.

One solution that I came up with (that I don't know it's correct to be doing so) is just including stdafx.h at the top of TestFuncs.h after the #pragma once. Now the project works file using precompiled headers or not.

Is this how it should be done, or is there a proper way of doing this?

Thank you.

1

1 Answers

5
votes

Don't #include "stdafx.h" in your library's public header file. By public header file, I mean the header file that clients of your library would #include.

Instead, only define the absolute minimum, and preferably use 100% portable code in this file. Also avoid using the STL if your library is going to be used by different compilers or platforms.

So suppose you have a public header file my_library.h which is implemented in gizmo.cpp. You would have the following:

gizmo.cpp

#include "stdafx.h"
#include "my_library.h"

int GizmoTronic()
{ 
  // ...
  return 42;
}

Also, off-topic, but use macro guards and not #pragma once which is not part of the C++ language, and therefore isn't supported by all compilers. It is a bad habit to get in to.

EDIT:

As for the question of DWORD and string not being defined when your header is #include-ed, I have 3 suggestions:

1) Only use portable datatypes. That is, datatypes defined by the Standard. DWORD is a microsoft invention (from decades ago). It is not part of the language, and it is not portable. Instead, use unsigned long or something else suitable.

2) Don't use string in your library's public interface if your library is going to be used by code compiled with a compiler other than yours. The reason is because string is defined completely in header files, so each compiler potentially has it's own implementation. One compiler's string might look different from another's.

3) Assuming #2 doesn't apply, feel free to #include any necesarry headers from the Standard Library at the top of your header. If you use string in your public interface, #include <string> in your header. (Just please do not using namespace std). Your header should be self-contained.

EDIT2:

Here is how I would declare your function:

void MyFunc(unsigned long a, const char* b);