gpt4 book ai didi

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

转载 作者:太空宇宙 更新时间:2023-11-04 06:00:57 24 4
gpt4 key购买 nike

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

struct some_v0{
char a;
int some_array[200];
char b;
}
struct some_v0{
char a;
int *some_array;
char b;
}
void some_api(void * some_struct, int version){
/* Depending on version the void pointer is cast to 2 different version of a struct*/
/* This is followed by some common code which is similar for both version of struct(as array access and pointer access have similar code)*/
}

由于数组访问和指针访问的代码相似,两个版本之间的唯一区别是 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 */
}
}

上面使用的代码块是相似的,因为数组访问和指针访问是相似的。我想避免上述情况中的重复代码。任何帮助表示赞赏。我正在寻找可以帮助我避免重复代码的解决方案。

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

编辑 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_v1 结构来访问 some_v0 结构,如果唯一的区别是 v0 中的数组与 v1 中的指针.

喜欢

struct some_v1 v1;

if(version == 0){
v1.a = ((struct some_v0 *) some_struct)->a;
v1.some_array = ((struct some_v0 *) some_struct)->some_array;
v1.b = ((struct some_v0 *) some_struct)->b;
} else if (version == 1)
v1 = *(struct some_v1 *) some_struct;
}

在此之后,结构 v1 可用于两个版本。


如果您稍后添加一个 some_v2 结构,它只向 some_v1 结构添加成员,那么您可以使用相同的技术。请记住在复制 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;
}

我建议将所有这些放在一个单独的函数中,以便在需要时可以轻松地重复使用。


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

struct some_v1 v1_np;  /* Non-pointer structure */
struct some_v1 *v1; /* the pointer we will work with */

if (version == 0) {
v1_np.a = ((struct some_v0 *) some_struct)->a;
v1_np.some_array = ((struct some_v0 *) some_struct)->some_array;
v1_np.b = ((struct some_v0 *) some_struct)->b;
v1 = &v1_np;
} else if (version == 1) {
v1 = (struct some_v1 *) some_struct;
}

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

关于基于版本参数转换函数参数以避免重复代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19442765/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com