C++11,用于处理C结构版本的不同版本的包装器类



编辑:我认为这个版本在运行时而不是编译时是已知的,所以我无法将其作为编译选项添加到gcc cmd中。这就是为什么我必须基于硬件报告的任何版本来支持这两个版本。

因此,我处理的固件需要支持同一个C结构版本的多个定义。我们根据供应商的C结构定义创建了自己的头文件,该头文件由内存控制器的接口文档定义。

// For simplicity lets pretend that this is the struct for version 1
typedef struct __attribute__((packed)) ver1 {
int x;
int y;
} ver1;

我还有一个现有的API,它已经使用了这个接口,需要用某种类包装器(我相信(或与现有的API配合得很好的包装器来替换。

void function_call(ver1 v1);

任何时候都只能存在结构的一个实例(ver1或ver2(针对某个fw版本的ver 1,以及针对某个fw版本的ver 2

ver2是我对ver1的扩展版本,我将其命名为ver2,希望使用某种工厂来选择正确的C样式结构。

typedef struct __attribute__((packed)) ver2 {
int x;
int y;
int w; // new
int z; // new
} ver2;

在创建ver2之前,我正在研究诸如装饰器或适配器设计模式之类的选项,我可以尝试在Hands-on design Patterns上找到的花哨的CRTP模板样式,但为了简单起见,我将用这个方案来说明我可能";附加";至ver1:

struct ver2 : public ver1 {
int w;
int z;
}

但后来我了解到C++不能保证相同的类布局C结构继承与C++POD结构继承以及潜在的对齐问题(我不太熟悉(,所以我认为这对我来说不是一个真正的选择。

我在stackoverflow上找到了这个例子,但我不喜欢在结构中添加include头的想法。如何在C应用程序中处理冲突的结构定义。这里有一个使用类似基类的类似示例针对同一接口的多个版本的C++设计(头文件中的枚举/结构(,由于继承对类布局的影响,我认为我甚至不能使用它。

除非有正当理由使用上面链接的技术,否则我正在考虑一个基于选择器返回正确版本的包装器类。首先,我将定义一个自由函数来利用它。

int get_fw_version(int target);

我正在研究C++11,所以我在自动返回类型推导方面受到限制,下面只是我试图思考的一些代码草案,没有完成,没有编译,只是说明了我的思考过程。自从IDK之后,我还没有考虑过如何进行构图。寻找想法。

int main() {
// Roughly how I would like to use it...
const int fw_ver = get_fw_version(target);
auto ver_inst = ver_factory(fw_ver);

function_call( ver_inst.get_data() );
return 0;
}

我不确定我是否可以在没有多态性的情况下做到这一点,其中基类有ver1,但派生类有ver2。

大致知道我现在的处境,我试着做CRTP,但我遇到了一个问题,即基类需要是一个模板,并且我不能使用异构的基类(例如shared_ptr(。尝试非CRTP方式IDK如何使用get_data((方法设置抽象基类。如果编译器不抱怨说基没有get_data方法,这是有道理的

// I can't figure out how to add T get_data() here without adding a template param. This base function is really to delegate common member methods and trying to keep a common base for polymorphism.
class base {
virtual ~base() = 0;
// ?? get_data() = 0 or some other method
};
class ver1_derived : public base
{
ver1 data;
public:
ver1_derived() = default;
ver1 get_data() {
return data;
}
};
class ver2_derived : public base
{
ver2 data;
public:
ver2_derived() = default;
ver2 get_data() {
return data;
}
};
// should be using unique_ptr but I can't at work....
shared_ptr<base> ver_factory(const int fw_ver) {
if(fw_ver <= 1) 
return make_shared<ver1_derived>();
return make_shared<ver2_derived>();
}

我最终放弃了一个继承方案,并根据模板类型选择了两个不同的代码路径。

所以

if(fw_ver <= 1) 
function_call<ver1>();
} else {
function_call<ver2>();
}

最新更新