【问题标题】:Using precompiled headers with a static library project将预编译头文件与静态库项目一起使用
【发布时间】:2023-03-24 13:14:01
【问题描述】:

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

到目前为止,我的 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 和字符串在当时都是未知的,因为它们是从 stdafx.h 文件定义的类型。

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

这是应该怎么做,还是有合适的方法?

谢谢。

【问题讨论】:

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


    【解决方案1】:

    不要在库的公共头文件中#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在你的header是#include-ed时没有定义的问题,我有3点建议:

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

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

    3) 假设 #2 不适用,请随时 #include 任何必要的标题来自标准库在标题的顶部。如果您在公共界面中使用string,请在标题中使用#include <string>。 (请不要using namespace std)。您的标头应该是独立的。

    编辑2:

    下面是我声明你的函数的方式:

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

    【讨论】:

    • 在我的示例中,静态库的公开函数使用 DWORD 类型作为其参数之一。您如何建议编写 TestFuncs.h 文件来解决这个问题,同时仍然能够将其包含在我的其他项目中?
    • 使用可移植的数据类型,而不是微软发明的东西。例如,不要使用DWORD,而是使用unsigned long
    • 相反,#pragma once 在跨平台代码中使用更加安全。大多数(如果不是全部)现代编译器,包括 GCC 3.4+,都能正确处理它。然而,它不是官方标准的一部分的原因是其设计中固有的问题。简而言之,#pragma once 比老式的#include 守卫更难编译器优化,其含义也更模糊。 (有关详细信息,请参阅此very well-written answer。)最后,您必须决定增加的便利是否值得更长的构建时间。
    猜你喜欢
    • 1970-01-01
    • 2012-12-02
    • 2022-09-26
    • 2010-12-08
    • 1970-01-01
    • 2014-01-15
    • 1970-01-01
    • 2018-01-20
    • 1970-01-01
    相关资源
    最近更新 更多