C 基于版本参数强制转换函数参数以避免重复代码

C 基于版本参数强制转换函数参数以避免重复代码,c,struct,C,Struct,我有一个如下的函数。它需要两个参数。一个是指向结构的空指针,另一个是版本号。根据传递的版本,void指针需要转换为几乎相似的2个结构(一个具有数组,另一个使用指针) 由于数组访问和指针访问都有相似的代码,所以两个版本之间的唯一区别是void指针的强制转换 我目前的方法如下 void some_api(void * some_struct, int version){ if(version == 0){ struct some_v0 v0; v0= *(

我有一个如下的函数。它需要两个参数。一个是指向结构的空指针,另一个是版本号。根据传递的版本,void指针需要转换为几乎相似的2个结构(一个具有数组,另一个使用指针)

由于数组访问和指针访问都有相似的代码,所以两个版本之间的唯一区别是void指针的强制转换

我目前的方法如下

void some_api(void * some_struct, int version){


    if(version == 0){
        struct some_v0 v0;
        v0= *(struct some_v0 *)some_struct;
        /* block of code which uses v0 */
    }
    if(version == 1){
        struct some_v1 v1;
        v1= *(struct some_v1 *)some_struct;
        /* block of code which uses v1 */
    }
}
上面使用的代码块是相似的,因为数组访问和指针访问是相似的。我希望在上述情况下避免重复代码。感谢您的帮助。我正在寻找一个解决方案,可以帮助我避免重复代码

注意:我无法更改结构成员的定义顺序。我知道,如果数组是结构定义中的最后一个元素,那么解决方案很简单。由于向后兼容的原因,我不允许更改struct元素的顺序

编辑1:我还有一个类似的API,需要填充输入结构并将其返回给调用函数

void some_api(void * some_struct, int version){


    if(version == 0){
        struct some_v0 *v0;
        v0= (struct some_v0 *)some_struct;
        /* block of code which uses v0  fill v0*/
    }
    if(version == 1){
        struct some_v1 *v1;
        v1= (struct some_v1 *)some_struct;
        /* block of code which uses v1. Fill v1 */
    }
}

我正在寻找一种解决方案,可以处理这种情况并避免重复代码。

至于您的通用性问题,您实际上可以使用
some\u v1
结构来访问
some\u v0
结构,如果唯一的区别是v0中的数组与v1中的指针

此后,两个版本都可以使用结构
v1


如果以后添加一个只向
some\u v1
结构添加成员的
some\u v2
结构,则可以使用相同的技术。复制v1结构后,请记住在v2结构中设置字段

比如说

struct some_v2
{
    char a;
    int *some_array;
    char b;
    int c;  /* New field in v2 */
};
那你就可以了

struct some_v2 v2;

if(version == 0){
    v2.a = ((struct some_v0 *) some_struct)->a;
    v2.some_array = ((struct some_v0 *) some_struct)->some_array;
    v2.b = ((struct some_v0 *) some_struct)->b;
    v2.c = 0;
} else if (version == 1)
    memcpy(&v2, some_struct, sizeof(struct some_v1));
    v2.c = 0;
} else {
    v2 = *(struct some_v2 *) some_struct;
}
我建议将所有这些放在一个单独的函数中,以便在需要时可以轻松地重用


在问题更新之后,如果您想使用指针,您可以这样做(考虑到只有两个版本的结构的原始版本):


如图所示,这与原始版本非常相似。这里的问题是v0和v1结构在任何方面都不兼容(请尝试检查这两种结构的大小,您可能会理解原因),这就是为什么您需要一个临时的
v1\u np
结构,您可以让它指向
v1

至于您的通用性问题,如果唯一的区别是v0中的数组与v1中的指针不同,那么实际上可以使用
some_v1
结构访问
some_v0
结构

此后,两个版本都可以使用结构
v1


如果以后添加一个只向
some\u v1
结构添加成员的
some\u v2
结构,则可以使用相同的技术。复制v1结构后,请记住在v2结构中设置字段

比如说

struct some_v2
{
    char a;
    int *some_array;
    char b;
    int c;  /* New field in v2 */
};
那你就可以了

struct some_v2 v2;

if(version == 0){
    v2.a = ((struct some_v0 *) some_struct)->a;
    v2.some_array = ((struct some_v0 *) some_struct)->some_array;
    v2.b = ((struct some_v0 *) some_struct)->b;
    v2.c = 0;
} else if (version == 1)
    memcpy(&v2, some_struct, sizeof(struct some_v1));
    v2.c = 0;
} else {
    v2 = *(struct some_v2 *) some_struct;
}
我建议将所有这些放在一个单独的函数中,以便在需要时可以轻松地重用


在问题更新之后,如果您想使用指针,您可以这样做(考虑到只有两个版本的结构的原始版本):


如图所示,这与原始版本非常相似。这里的问题是v0和v1结构在任何方面都不兼容(尝试检查这两个结构的
sizeof
,你可能会理解为什么),这就是为什么你需要一个临时的
v1\u np
结构,你可以让它指向
v1

我解决这个问题的方法

我没有使用2个版本的struct,而是在一些_v0中引入了一个新的struct成员,如下所示。 注意:我不会在这里更改结构成员的顺序

struct some_v0{
    char a;
    int some_array[200];
    char b;
    int *some_array_v1;
};
API函数可以实现为:

void some_api(void * some_struct, int version){
    struct *some_v0 v0= (some_v0 *)ptr;
    int *ptr; /*pointer we will be working on*/
    if (version == 0) {
         ptr=some_v0->some_array;
    } else if (version == 1) {
         ptr=some_v0->some_array_v1;
    }
/*Common code block which uses ptr wherever some_arry is used. All other members can be dereferenced using v0*/
}

这避免了重复代码,也可以处理api版本。这还负责返回struct pointer中的值,以便调用函数可以使用它。

我解决此问题的方法

我没有使用2个版本的struct,而是在一些_v0中引入了一个新的struct成员,如下所示。 注意:我不会在这里更改结构成员的顺序

struct some_v0{
    char a;
    int some_array[200];
    char b;
    int *some_array_v1;
};
API函数可以实现为:

void some_api(void * some_struct, int version){
    struct *some_v0 v0= (some_v0 *)ptr;
    int *ptr; /*pointer we will be working on*/
    if (version == 0) {
         ptr=some_v0->some_array;
    } else if (version == 1) {
         ptr=some_v0->some_array_v1;
    }
/*Common code block which uses ptr wherever some_arry is used. All other members can be dereferenced using v0*/
}

这避免了重复代码,也可以处理api版本。这还负责返回struct pointer中的值,以便调用函数可以使用它。

“上面使用的代码块相似…”相似还是相等?也许你想向我们展示这段有问题的代码?@alk代码块是相等的。在我目前的解决方案中,唯一不同的是使用V0和其他用途V1。你绝对必须使用C或是C++吗?@ Raja只有C CAB。没有C++(“上面的代码块是相似的……”类似或相等的?也许你想把这个代码显示给我们看看?@ ALK代码块是相等的。我目前的解决方案的唯一区别是使用V0和其他用法V1。你绝对必须使用C还是C++?”@ Raja只有C CAB。没有C++。(这看起来不错。如果
struct some_v1;
是指针怎么办?
struct some_v1*v1;
。我希望这也适用于指针,对吧?@Ravichandra不幸的是,在使用指针时它不会很好地工作(即,使
some_v1
结构指针指向
某些数据
)。问题是,如果您传入一个
v0
结构,则
b
成员在
v0
结构中的偏移量与
v1
结构中的偏移量不相同。此外,如果您以后添加
v2
结构,则不能只制作一个指针
v2
,并使其指向
v1
结构cture,当你访问
v2
结构的
c
成员时,你将在分配的内存之外读取(或者更糟的是,写入)。@Ravichandra然而,隧道的尽头有一盏灯。如果,我的意思是如果,
某个结构是实际的