2013-07-10 145 views
2

我正在將專有文件格式的文件轉換代碼寫入一個更通用的代碼。我的目標是支持製造商文件格式的多個版本。如何包含同一頭文件的兩個不同版本?

我有相同的專有標題的多個版本。頭文件定義了包含主文件頭文件的各種結構體(該文件只是一個大頭文件,後面是原始數據)。

我需要讀取源文件的前4個字節來確定文件版本。文件版本反過來告訴我哪個版本的C-structs被用來創建文件。

的問題是:

  1. 我不能修改專有頭
  2. 的頭不使用命名空間或類
  3. 有在頭文件中定義宏的好幾個

可能的解決方案:

  • 建立每個文件的版型不同的轉換器的二進制文件:-(
    • 不方便的用戶和開發者
  • 每個版本動態加載庫
    • 該轉換器是插件爲導向,所以已經是一個很多這樣的情況

我曾嘗試與命名空間黑客:

namespace version1 { 
    #include "version1.h" 
} 

namespace version2 { 
    #include "version2.h" 
} 

int main (void) { 
    version1::header *hdr = new version1::header; 
    return 0; 
} 

但是這不會因爲包含警衛而起作用,並且因爲在每個頭文件中重新定義了多個宏。

有沒有一種優雅的方式來處理這個問題?

+0

標題 - 它們是如何「C」?你只使用頭文件,沒有庫或支持它們的'.c'或'.cpp'文件?你說你不能修改頭文件:你可以把頭文件作爲輸入,代碼生成衍生物來編譯? – Yakk

+0

它們是純粹的C頭文件。甚至沒有任何函數聲明,只是C結構。 – joe

+0

@MatsPetersson可能有一個合理的方法。 – Yakk

回答

5

你可以用一個向前聲明使用兩個不同的源文件,一起:

// Forward declare in main.cpp: 

namespace version1 
{ 
    struct header; 
} 

namespace version2 
{ 
    struct header; 
} 

// version1.cpp: 

namespace version1 
{ 
     #include <version1.h> 
} 

version1::header* new_v1_header() 
{ 
    return new version1::header; 
} 

// other functions using `version1::header` 

// version2.cpp: 

namespace version2 
{ 
     #include <version2.h> 
} 

version2::header* new_v2_header() 
{ 
    return new version2::header; 
} 

// other functions using `version2::header` 

另一種方法是實現一個包裝類,它有一個基地 - 類只是一個空殼:

class header_base 
{ 
    virtual int func1(char *stuff) = 0; 
    ... many other virtual functions. 
}; 

// Create implementation of header_v1 or header_v2: 
header_base* make_header(unsigned int magic); 

header_base.cpp:

#include "header_v1.h" 
#include "header_v2.h" 

header_base* make_header(unsigned int magic) 
{ 
    switch(magic) 
    { 
     case Magic_V1: 
      return new header_v1; 
     case Magic_V2: 
      return new header_v2; 
     default: 
      assert(0); 
      return 0; 
    } 
} 

,然後實現,在兩個單獨的

在headerv1

。H:

class header_v1 : public header_base 
{ 
    int func1(char *stuff); 
    ... 
}; 

header_v1.cpp:

#include "header1.h" 

int header_v1::func1(char *stuff) 
{ 
    ... 
    return 17; 
} 

而對於header_v2.h和header_v2.cpp相似。

+1

如果圖書館不是標題,這不是一個特別好的想法,因爲它與混亂的名字混淆。請參閱http://stackoverflow.com/a/6670753/46642。 –

+0

準確地說,我會做。我也可能會聲明一個包裝由標題聲明的功能的ABC,並且具有ABC的2個具體派生;每個版本一個。 –

+0

結構只定義了數百種基元類型,沒有功能。爲了動態使用header_base,我必須存儲一個指向頂層結構的指針,然後爲上百個結構成員中的每一個創建虛擬getter,然後爲每個派生包裝類的每個成員實現getter。 – joe

相關問題