gpt4 book ai didi

c - 在 C 中将不同的函数返回类型存储在一个 union 中

转载 作者:行者123 更新时间:2023-11-30 19:32:39 25 4
gpt4 key购买 nike

我在用语言表达我的目标时遇到困难,所以我不太确定如何表达这一点。

假设我有两个具有以下签名的函数:

myBigStruct_t function1()
int function2()

具有 myBigStruct_t 的定义(存储大量数据并且位于其他位置)和可以支持两种返回类型大小的 union 定义:

typedef union myUnion{
myBigStruct_t A;
int B;
} myData_t;

union my2ndUnion{
myData_t data_;
char myArray[sizeOf(myData_t)];
} un2;

我可以执行以下操作:

un2.myArray = function1();
...
if( something ){
myExpress = un2.data_.A;
else{
myOtherExpress = un2.data_.B;
}
...
un2.myArray = function2();
if( something ){
myExpress = un2.data_.A;
else{
myOtherExpress = un2.data_.B;
}

我知道数组数据通常是通过引用传递的,但大多数 C 编译器都有一种传递大型数据类型的方法,这些数据类型至少看起来是按值传递的(无论是否使用 secret 指针)。

我知道这有点做作;我只是想在 union 中取得领先。

最佳答案

是的,这正是 union 所做的。我认为这回答了您的问题(如果没有,请告诉我),但我会提供更多背景信息。

如果myBigStruct_t定义如下:

typedef struct {
char someChars[256];
int someInts[512];
} myBigStruct_t;

然后,当您从 function1() 进行赋值时,数据就会被复制。不涉及 secret 指针。

另一方面,如果 myBigStruct_t 定义如下:

typedef struct {
char *someChars; //This gets malloc'd in function1
int *someInts; //This gets malloc'd in function1
} myBigStruct_t;

然后数据是通过引用传递的,即数据没有被复制。

请注意,由于 function1myArray 的返回值类型不匹配,您的代码将无法正常工作,function2 的返回值也是如此。您必须分配特定的 union 成员:

un2.myArray.data_.A = function1();
un2.myArray.data_.B = function2();

我认为没有任何理由不这样做。

编辑(回应您的评论):

为什么不直接将数组作为参数传递而不是返回值?函数原型(prototype)如下:void foo(void* buffer, size_t buffer_len)。我假设您完全理解指针(否则函数指针可能不是解决您的问题的正确方法)。完整的程序可能如下所示:

//All the functions use this prototype, although it isn't strictly necessary (your loop would just have to be smarter)
typedef void(*GenericFunctionCall)(void* buffer, size_t buffer_len);

//A struct with only a few bytes
typedef struct SmallStruct_s{
char value;
} SmallStruct_t;

//A struct with more bytes
typedef struct BigStruct_s {
char value[1024];
} BigStruct_t;

//Defining this makes it easy to get the maximum size of all the structs
typedef union AllStructs_s {
SmallStruct_t small;
BigStruct_t big;
} AllStructs_t;

//This function takes the buffer, casts it to a SmallStruct_t, and then does something with it (presumably sets param->value to something)
void smallFunction(void* buffer, size_t buffer_len) {
SmallStruct_t * param = (SmallStruct_t*)buffer;

//do something with param
}
//This function does the same with BigStruct_t
void bigFunction(void* buffer, size_t buffer_len) {
BigStruct_t * param = (BigStruct_t*)buffer;

//do something with param
}



int main() {
//This allocates memory for all the values generated by smallFunction and bigFunction.
AllStructs_t param;

//This is your table of function pointers
GenericFunctionCall functions[2];
functions[0] = smallFunction;
functions[1] = bigFunction;

//Loop through the functions and do something with the results
for (uint32_t function_index = 0; function_index < 2; ++function_index) {
functions[function_index]((void*)&param, sizeof(AllStructs_t));

//Do something with param here
}
}

第二次编辑:

好的,我现在明白你想做什么了。您不能使用 union between 来接受任意值,在这种情况下, union 与任何其他数据类型没有什么不同(即我无法分配 BigStruct_t = SmallStruct_t)。

原因如下:当编译器生成代码来处理函数的返回值时,它会使用调用者的内存来存储该值。因此,您无法获取指向函数返回值的指针。用编译器的话说:函数的返回值不是 lvalue 。解决此问题的选项是:

  • 将函数的返回类型存储在表中,并使用它分配适当的变量
  • 为表中的每个函数编写一个包装函数,并将其返回类型从返回值转换为指针参数。调用包装器而不是原始函数
  • 完全重构代码

关于c - 在 C 中将不同的函数返回类型存储在一个 union 中,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46857452/

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