2017-08-25 53 views
6

我们正在努力在两个C++代码库,我们称之为一个,则一个是构建作为一个库,并分发头文件.h.a文件如何确定使用相同宏的不同C++代码库?

比方说,有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(); 

在代码库一个,我们默认将使TRACK_THREAD_OWNER_FOR_DEBUG,只是最终发布前一天可以更改它。

我们投中了一些硬错误,因为TRACK_THREAD_OWNER_FOR_DEBUG一个不同,而导致内存崩溃,因为sizeof(Lock)是两个不同的库。

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

回答

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函数名称应该包含错误文本。

+0

是的,链接错误也是可以接受的。 – ZijingWu

0

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

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

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

相关问题