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

Mat*_*hew 1 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
}
Run Code Online (Sandbox Code Playgroud)

TestFuncs.h

#pragma once
void MyFunc(DWORD a, std::string b);
Run Code Online (Sandbox Code Playgroud)

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

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

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

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

谢谢.

Joh*_*ing 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;
}
Run Code Online (Sandbox Code Playgroud)

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

编辑:

至于你的标题是-ed 的问题DWORDstring没有定义#include,我有3个建议:

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

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

3)假设#2不适用,请随意使用#include标题顶部标准库中的任何necesarry 标题.如果您string在公共界面中使用,请#include <string>在标题中使用.(请不要using namespace std).您的标题应该是自包含的.

EDIT2:

以下是我将如何声明您的功能:

void MyFunc(unsigned long a, const char* b);
Run Code Online (Sandbox Code Playgroud)

  • 相反,`#pragma once`在跨平台代码中使用是安全的.大多数(如果不是全部)现代编译器(包括GCC 3.4+)都能正确处理它.然而,它不是官方标准的一部分原因是因为其设计中固有的问题.简而言之,"#pragma once"对于编译器来说更难以优化,并且其含义比传统的`#include`守卫更加含糊不清.(有关详细信息,请参阅[非常好的答案](http://stackoverflow.com/a/1696194/266704).)最后,您必须确定增加的便利性是否值得更长的构建时间. (2认同)