将预编译头与静态库项目一起使用

时间:2010-11-15 03:27:18

标签: c++ static-libraries precompiled-headers

我需要一些关于如何设置项目的建议。我正在构建一个静态库,并想知道在我走得太远之前,我使用预编译头的方式是否正确。

到目前为止,我的stdafx文件只包括(对于像DWORD这样的类型)和(对于std :: string)。

我构建了一个名为TestFuncs.cpp / h

的简单cpp / header组合

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);

这里的代码编译正确。我遇到的问题是当我想在另一个项目中使用这个静态库时,我通常会做#include“path_to_my_static_lib_project / TestFuncs.h”

但是,这个问题基于TestFuncs.h,当时DWORD和string都是未知的,因为它们是从stdafx.h文件定义的类型。

我提出的一个解决方案(我不知道这样做是正确的)只是在#pragma一次之后将stdafx.h包含在TestFuncs.h的顶部。现在,项目使用预编译头文件工作文件。

这是应该怎么做的,还是有正确的方法呢?

谢谢。

1 个答案:

答案 0 :(得分:5)

不要在库的公共头文件中#include "stdafx.h"。通过公共头文件,我的意思是您的库的客户端#include的头文件。

相反,只定义绝对最小值,最好在此文件中使用100%可移植代码。如果您的库将由不同的编译器或平台使用,也请避免使用STL。

假设您有一个公共头文件my_library.h,它在gizmo.cpp中实现。您将拥有以下内容:

gizmo.cpp

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

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

此外,偏离主题,但使用宏保护,而不是#pragma once,它不是C ++语言的一部分,因此并非所有编译器都支持。进入是一个坏习惯。

编辑:

关于DWORDstring在标题为#include时未定义的问题,我有3条建议:

1)仅使用可移植数据类型。也就是说,标准定义的数据类型。 DWORD是一项微软发明(几十年前)。它不是语言的一部分,也不是可移植的。相反,请使用unsigned long或其他合适的东西。

2)如果您的库将由使用非您的编译器编译的代码使用,请不要在库的公共接口中使用string。原因是因为string完全在头文件中定义,所以每个编译器都可能拥有它自己的实现。一个编译器的string可能看起来与另一个编译器不同。

3)假设#2不适用,请随意从标题顶部的标准库 #include string任何necesarry标题。如果您在公共界面中使用#include <string>,则标题中为using namespace std。 (请不要void MyFunc(unsigned long a, const char* b); )。你的标题应该是自包含的。

EDIT2:

以下是我宣布你的功能的方法:

{{1}}