如何包含同一个header的两个不同版本? [英] How to include the two different versions of the same header?

查看:105
本文介绍了如何包含同一个header的两个不同版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在将文件转换代码从专有文件格式写入一个通用文件。我的目标是支持制造商文件格式的多个版本。



我有多个版本的相同的专有头。头文件定义了包含主文件头文件的各种结构体(文件只是一个大的头文件,后跟原始数据)。



我需要读取前4个字节的源文件来确定文件版本。文件版本反过来告诉我使用C-structs的哪个版本来创建文件。



问题是:


  1. 我无法修改专有标头

  2. 标头不使用命名空间或类


可能的解决方案:




  • 为每个文件版本类型构建不同的转换器二进制文件:-(

    • 用户和开发人员都不便


  • 动态加载每个版本的库

    • 转换器是面向插件的,所以已经有很多发生




我试过黑客使用命名空间:

 命名空间version1 {
#includeversion1.h
}

命名空间version2 {
#includeversion2.h
}

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

但是这不会工作,因为包含守卫,

解决方案



是否有优雅的处理方式? / div>

您可以使用两个不同的源文件以及转发声明:

  .cpp:

命名空间version1
{
struct header;
}

命名空间version2
{
结构头;
}






  // version1.cpp:

命名空间version1
{
#include< version1.h>
}

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

//使用`version1 :: header'的其他函数






  // version2.cpp:

命名空间版本2
{
#include < version2.h>
}

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

//使用`version2 :: header'的其他函数

另一个替代方法是实现一个包装类,它的基类只是一个空壳:

  header_base 
{
virtual int func1(char * stuff)= 0;
...许多其他虚拟函数。
};

//创建header_v1或header_v2的实现:
header_base * make_header(unsigned int magic);

header_base.cpp:

  #includeheader_v1.h
#includeheader_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;
默认值:
assert(0);
return 0;
}
}

$ header



在headerv1.h中:

  
int func1(char * stuff);
...
};

header_v1.cpp:

  #includeheader1.h

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

与header_v2.h和header_v2.cpp类似。


I am writing file conversion code from a proprietary file format to one more generic. My goal is to support multiple versions of the manufacturer's file format.

I have a multiple versions of the same proprietary headers. The headers define various structs which comprise the main file header (the file is simply a large header followed by raw data).

I need to read the first 4 bytes of the source file to determine the file version. The file version, in turn, tells me which version of the C-structs was used to create the file.

The issues are:

  1. I can't modify the proprietary headers
  2. The headers do not use namespaces or classes
  3. There are a good handful of macros defined in the headers

Possible solutions:

  • Build different converter binaries for each file version type :-(
    • Inconvenient for both user and developer
  • Dynamically load libraries for each version
    • The converter is plugin-oriented, so there's already a lot of this happening

I have tried hacking with namespaces:

namespace version1 {
    #include "version1.h"
}

namespace version2 {
    #include "version2.h"
}

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

But this won't work because of include guards, and because there are multiple macros are redefined in each header.

Is there an elegant way to handle this?

解决方案

You could use two different source files, together with a forward declaration:

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

Another alternative is to implement a wrapper class, which has a base-class that is just an empty shell:

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;
    }
}

and then implement, in two separate

in 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;
}

And similar for header_v2.h and header_v2.cpp.

这篇关于如何包含同一个header的两个不同版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆