2013-07-10 144 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

相关问题