【问题标题】:how to prohibit other developers to #include a third party header in C++如何禁止其他开发人员在 C++ 中#include 第三方标头
【发布时间】:2011-12-06 13:12:48
【问题描述】:

所以有一个第三方库有一个你需要包含的头文件才能使用它。由于库的实现不是面向对象的,所以我写了一个类来封装库的所有用法,所以如果需要替换它,我可以修改该类的实现。

由于其他开发人员将在相同的代码库中工作,我想要一种方法在他们包含库时给他们一个错误。这是为了避免到处都有对图书馆的引用。

例如,如果他们这样做:

#include "cool_library.h"

他们收到一条错误消息:

do not include directly cool_library.h, instead use the cool_library_wrapper class

这可能吗?我正在使用 GNU GCC

【问题讨论】:

  • 我认为更简洁的解决方案是将检查添加到您的构建过程(makefile 或您使用的任何内容)。您可以在使用时添加 cppcheck 或其他代码完整性检查器。 C 预处理器并不完全适合这项工作。
  • grep 'some_header.h' include/ src/ -R 应该这样做。并且不要忘记解雇屡犯者。这不是源代码层面要解决的问题。

标签: c++ gcc include precompile


【解决方案1】:

由于您使用的是gcc,因此您可以使用预处理器的#include_next 功能:在查找头文件时具有更高优先级的目录中创建与第三方同名的头文件。在您的标头版本中使用类似

#if WRAPPER_HEADER_HAS_BEEN_INCLUDED
#  include_next <cool_library.h>
#else
#  error ...
#endif

【讨论】:

    【解决方案2】:

    您可以在 #ifndef 块中使用 #error 预处理器指令。

    例如在原始 .h 文件中有这个:

    #ifndef COOL_LIBRARY_WRAPPER_CLASS_INCLUDED
    #error "do not include this file directly
    #endif
    

    在包装类的头文件中这样做:

    #define COOL_LIBRARY_WRAPPER_CLASS_INCLUDED
    

    【讨论】:

    • 我忘了说我不能修改第三方代码,如果可以的话,这会很好,但我不能。谢谢
    • @Makako:看来你想要魔法。您希望标头具有不同的行为,而无需对其进行修改。
    【解决方案3】:

    这只有在您可以修改cool_library.h 文件的情况下才有可能。你可以这样做:

    cool_library.h

    #ifndef INCLUDED_FROM_COOL_LIBRARY_WRAPPER
    #error do not include directly cool_library.h, instead use the cool_library_wrapper class
    #endif
    
    .. remainder of original cool_library.h
    

    cool_library_wrapper.h

    #define INCLUDED_FROM_COOL_LIBRARY_WRAPPER
    #include "cool_library.h"
    
    ... your wrapper
    
    #undef INCLUDED_FROM_COOL_LIBRARY_WRAPPER
    

    当然,您仍然无法阻止您的同事自己定义INCLUDED_FROM_COOL_LIBRARY_WRAPPER 并包含原始头文件。这是一个没有技术解决方案的社会问题。

    【讨论】:

    • 我不能修改cool_library.h,否则这样就很好了
    【解决方案4】:

    如果您通常包含一些项目范围的标头,您可以检查第三方标头中是否存在包含保护,例如

    // third_party.h
    #ifndef THIRD_PARTY_H
    #define THIRD_PARTY_H
    ...
    

    // your_project_wide.h
    ...
    #ifdef THIRD_PARTY_H
    #warning "Please include "cool_library.h"
    #endif
    ...
    

    注意事项:#warning 是一个 gcc 扩展,所有这些都依赖于在项目标头 (which you might not want to do) 之前包含的外部依赖项。

    【讨论】:

    • 因为我无法修改第三方标头,但它被适当的#ifndef _X_ #define _X_ #endif 包裹,我可以做这样的事情来警告其他人。但是,他们需要包含项目范围的 *.h 文件。谢谢
    【解决方案5】:

    不要将&lt;cool_library.h&gt; 放在正常的构建包含路径中。您可以使用特殊的 CFLAGS 为您的包装器授予访问权限,也可以使用更明确的路径(如 &lt;vendor/xyz/cool_library.h&gt;)从更高级别的包含路径访问它。

    另一种基于路径的方法是将本地&lt;cool_library.h&gt; 放在包含路径的前面,并使用上面的#ifdef/#error 方法。如果存在魔术定义,则存根标头可以使用更明确的路径来获取真正的标头。 (如果您包含与正在读取的标头完全相同的内容,则某些编译器会继续搜索路径)

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 1970-01-01
      • 1970-01-01
      • 2017-11-23
      • 1970-01-01
      • 2016-10-15
      • 1970-01-01
      相关资源
      最近更新 更多