如何使用相同的宏确保不同的C ++代码库?

时间:2017-08-25 03:18:33

标签: c++ macros

我们正在制作两个C++代码库,我们称之为 A B A 是构建为一个库,并将标题文件.h.a文件分发到 B

假设 A 中有Lock.h个文件如下:

// Lock.h in code base A
class Lock {
    ... ...
#ifdef TRACK_THREAD_OWNER_FOR_DEBUG
    virtual int GetLockOwner();
#endif
    ... ...
private:
    CriticalSection section;
#ifdef TRACK_THREAD_OWNER_FOR_DEBUG
    int threadOwner;
#endif
};

// Caller.cc in code base B
#include "xxx/xxx/Lock.h"
Lock lockObject;
lockObject.Lock();

在代码库 A 中,我们默认启用TRACK_THREAD_OWNER_FOR_DEBUG,并可能在最后发布日之前更改它。

我们遇到了一些难题,因为TRACK_THREAD_OWNER_FOR_DEBUG A B 方面有所不同,导致内存损坏,因为sizeof(Lock)在两个方面有所不同图书馆。

那么如何防止此错误?如果构建宏caller.cc在两个项目中不同,那么在构建TRACK_THREAD_OWNER_FOR_DEBUG文件时是否可以触发编译器错误?

2 个答案:

答案 0 :(得分:6)

不可能将此转换为编译器错误,但是应该可以使用静态保护变量将其变为合理清晰的链接器错误:

//  Foo.hpp - library header file
#pragma once

class Foo
{
    public: Foo();
#ifdef VTT_CONDITION
    int m_field;
#endif
};

class ConditionGuard
{
    public:
    ConditionGuard(void) noexcept
    {
    #ifdef VTT_CONDITION
        CONDITION_ON();
    #else
        CONDITION_OFF();
    #endif
    }

#ifdef VTT_CONDITION
    private: static void CONDITION_ON(void);
#else
    private: static void CONDITION_OFF(void);
#endif
};

static ConditionGuard const condition_guard{};

// Foo.cpp - library implementation file 
#include "Foo.hpp"

Foo::Foo(void) {}

#ifdef VTT_CONDITION
void ConditionGuard::CONDITION_ON(void) {}
#else
void ConditionGuard::CONDITION_OFF(void) {}
#endif

现在,当用户代码包含库标题Foo.hpp时,它还将触发condition_guard静态变量的构造,该静态变量将根据受保护的条件调用库函数。因此,如果存在包含Foo.hpp的翻译单元,其中VTT_CONDITION的定义与编译库中的不同,那么将丢失CONDITION_ONCONDITION_OFF的链接器错误。 CONDITION_ONCONDITION_OFF函数名称应包含错误文本。

答案 1 :(得分:0)

一个选项是将A的完整代码包含到项目B中。您要通过将A编译到静态库中来做什么?

我认为你最好的选择是根据目标生成不同的.a文件。设置TRACK_THREAD_OWNER_FOR_DEBUG时为libA_debug.a,而不设置为libA.a。

然后,您可以根据您是编译调试版还是发布版来将库设置为链接B.