[英]How can I create a function that takes a parameter of unknown type in C?
Say I have the following code: 说我有以下代码:
struct test* t1;
t1 = get_t(1);
... where get_t
is: ...其中
get_t
是:
struct test* get_t(int);
How can I refactor the above code and put it in a function? 如何重构上面的代码并将其放入函数中? Something like the following:
类似于以下内容:
void r1(?* t, ?* (fn*)(int)) {
t = fn(1);
}
/* ... */
struct test* t1;
r1(t1, &get_t);
使用void *param
,指向任何东西的指针......通常在glib中用作gpointer
I have two ideas: 我有两个想法:
[1] Pass void
pointer to the variable/object, and type cast it in the function. [1]将
void
指针传递给变量/ object,并在函数中输入。
[2] Make a union of all datatypes along with an integer datatype which will identify which datatype variable in the union does hold the actual data. [2]将所有数据类型与一个整数数据类型结合起来,这将确定联合中哪个数据类型变量保存实际数据。 Pass this union as value or as
void *
将此联合作为值或
void *
传递
struct _unknown {
union {
int a;
float b;
char c;
double d;
} data;
int type;
} unknown;
.
.
.
if (unknown.type == FLOAT)
{
/* Process variable b */
}
else if (unknown.type == INT)
{
/* Process variable a */
}
.
.
.
Something like this. 像这样的东西。
You can hash define the FLOAT
and INT
and others as unique values. 您可以将
FLOAT
和INT
以及其他值哈希定义为唯一值。
Or simply 或者干脆
struct _unknown {
void *data;
int type;
} unknown;
.
.
.
if (unknown == FLOAT)
{
/* process (float *) data */
}
else if (unknown == INT)
{
/* process (int *) data */
}
else if (unknown == MY_DATA_TYPE)
{
/* process (my_data_type *) data */
/* where my_data_type could be a typedef, or struct */
}
If you have gcc, you can use this more typesafe version: 如果你有gcc,你可以使用这个更安全的版本:
#define r1(varp,func) ({ \
typeof(**varp)* (*_func_)(int); \
typeof(**varp)* _varp_ = (varp); \
_func_ = (func); \
r1_((void**)(_varp_),(void*(*)(int))_func_); \
})
void r1_(void** varp,void*(*func)(int))
{
*varp = func(1);
}
Call as: 呼叫:
struct test* get_t(int);
struct test* t1;
r1(&t,get_t);
(You dont need to use &
on functions, they decay to pointers automatically, like arrays). (你不需要在函数上使用
&
,它们会像数组一样自动衰减到指针)。 This checks that t
is a pointer, and that get_t
is a function returning that type of pointer. 这检查
t
是一个指针, get_t
是一个返回该指针类型的函数。 _varp_
is technically unneeded, but keeps the argument evaluation in the right order. _varp_
在技术上是不需要的,但保持参数评估的顺序正确。
If you don't have gcc, you can still do this, but you have to provide the type explicitly: 如果你没有gcc,你仍然可以这样做,但你必须明确提供类型:
#define r1(T,varp,func) do { \
T*(*_func_)(int); \
T* _varp_ = (varp); \
_func_ = (func); \
r1_((void**)(_varp_),(void*(*)(int))_func_); \
} while(0)
void r1_(void** varp,void*(*func)(int))
{
*varp = func(1);
}
Call as: 呼叫:
struct test* get_t(int);
struct test* t1;
r1(struct test*,&t,get_t);
not quite as safe, and more redundant, but still fairly good. 不太安全,多余,但仍然相当不错。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.