2017-08-25 16 views
6

Chúng tôi đang làm việc trên hai cơ sở C++ mã, chúng ta hãy gọi nó MộtB, các Một là một xây dựng như một thư viện, và phân phối các tập tin tiêu đề .h.a tập tin để B.Làm thế nào để đảm bảo cơ sở mã C++ khác nhau sử dụng cùng một macro?

Hãy nói rằng có Lock.h tập tin trong Một như sau:

// 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(); 

Trong mã cơ sở Một, chúng tôi theo mặc định sẽ cho phép TRACK_THREAD_OWNER_FOR_DEBUG và có thể thay đổi nó ngay trước ngày phát hành chính thức.

Chúng tôi nhấn một số lỗi khó vì TRACK_THREAD_OWNER_FOR_DEBUG là khác nhau trong MộtB, và gây ra tham nhũng bộ nhớ vì sizeof(Lock) là khác nhau trong hai thư viện.

Vậy làm thế nào để bảo vệ khỏi lỗi này? Chúng tôi có thể kích hoạt lỗi trình biên dịch khi xây dựng tệp caller.cc nếu macro dựng hình TRACK_THREAD_OWNER_FOR_DEBUG khác nhau trong hai dự án không?

Trả lời

6

Không thể để làm điều này vào lỗi biên dịch, tuy nhiên chúng ta có thể thực hiện điều này vào lỗi mối liên kết hợp lý rõ ràng bằng tĩnh bảo vệ biến:

// 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 

Bây giờ khi mã người dùng bao gồm thư viện tiêu đề Foo.hpp nó sẽ cũng kích hoạt việc xây dựng biến số tĩnh condition_guard sẽ gọi hàm thư viện tùy thuộc vào điều kiện được bảo vệ. Vì vậy, nếu có đơn vị dịch bao gồm Foo.hpp trong đó VTT_CONDITION được xác định khác với thư viện được biên dịch thì sẽ có lỗi liên kết cho thiếu CONDITION_ON hoặc CONDITION_OFF. Các tên hàm CONDITION_ONCONDITION_OFF phải chứa văn bản lỗi.

+0

Có, lỗi liên kết cũng được chấp nhận. – ZijingWu

0

Một tùy chọn là chỉ bao gồm mã đầy đủ cho A vào dự án B. Bạn đang cố gắng làm gì bằng cách biên dịch A thành thư viện tĩnh?

Tôi nghĩ rằng bạn là lựa chọn tốt nhất là tạo các tệp .a khác nhau tùy thuộc vào mục tiêu. tức là libA_debug.a khi TRACK_THREAD_OWNER_FOR_DEBUG được đặt, libA.a khi không được.

Sau đó, bạn có thể đặt thư viện để liên kết B dựa trên việc bạn đang biên dịch phiên bản gỡ lỗi hay phiên bản phát hành.

Các vấn đề liên quan