低冗长的 C 泛型继承
C generic inheritance with low verbosity
拥有:
struct packet_sample_t {
int common_id;
int some;
char data[];
float foo;
}
具有以下功能:
void dispatch_packet(void *packet);
我的目标是解析数据包 ID,然后调用其处理程序,但我无法从 void *
检索结构变量 common_id
。
我想用高级语言创建类似 interface
的东西,假设我所有的数据包结构都应该有变量 common_id
.
所以我正在寻找可以像下面这样工作的东西:
struct packet_base {
int common_id;
}
void dispatch_packet(void *packet) {
int common_id = ( (packet_base *)packet )->common_id;
switch(common_id) {...}
}
void test() {
packet_sample_t packet = {.common_id = 10, ...};
dispatch_packet((void *) &packet); //this function should retrieve `common_id`
packet_other_t other = {.common_id = 1};
dispatch_packet((void *) &other); // again with another packet
}
我对 C 语言不是很熟悉,我真的不知道我该怎么做。但简单来说,我希望能够将一个数据包投射到它的packet_base,它们共享一个公共变量。
编辑:示例中有更多详细信息
您可以使用union
将不同类型的数据聚合到一个结构中
struct packet1_t
{
// Packet1 specific data
......
}
struct packet2_t
{
// Packet2 specific data
......
}
struct packet_t
{
int common_id;
union
{
struct packet1_t packet1;
struct packet2_t packet2;
......
}
} packet;
现在,您可以根据 ID 从联合中选择正确的类型:
int do_something_with_packet(packet_t packet)
{
switch (packet.common_id)
{
case 1:
do_something_with_packet1(packet.packet1);
break;
case 2:
do_something_with_packet2(packet.packet2);
break;
..................
}
....
}
你的技术是有效的。有 a number of ways to do struct inheritance in C, and this is one of them. 21st Century C might be a good read for you as well as Object-Oriented Programming with ANSI C.
您在声明和使用您的结构和类型时遇到了问题。让我们看看这个。
struct packet_base {
int common_id;
};
它的类型是 struct packet_base
。如果要声明指向此类型的指针,则需要编写 struct packet_base *packet
。如果你想转换这种类型的变量,它是 (struct packet_base *)thing
.
这很烦人,因此您通常使用 typedef
为结构声明一个类型别名。语法是 typedef <type> <alias>
typedef struct {
int common_id;
} packet_base_t;
这表示类型 struct { int common_id; }
是 packet_base_t
的别名。现在您可以使用 packet_base_t
作为类型。 packet_base_t *packet
声明一个指针并 (packet_base_t *)thing
转换。
修复后,再加上一些小错误,它就可以工作了。请参阅 What is the difference between char array vs char pointer in C? 了解 char *data
与 char data[]
。
typedef struct {
int common_id;
int some;
char *data;
float foo;
} packet_sample_t;
typedef struct {
int common_id;
} packet_base_t;
void dispatch_packet(void *arg) {
// It's simpler to cast to a new variable once then to muck
// up the code with casts.
packet_base_t *packet = (packet_base_t *)arg;
int common_id = packet->common_id;
printf("id: %d\n", common_id);
}
拥有:
struct packet_sample_t {
int common_id;
int some;
char data[];
float foo;
}
具有以下功能:
void dispatch_packet(void *packet);
我的目标是解析数据包 ID,然后调用其处理程序,但我无法从 void *
检索结构变量 common_id
。
我想用高级语言创建类似 interface
的东西,假设我所有的数据包结构都应该有变量 common_id
.
所以我正在寻找可以像下面这样工作的东西:
struct packet_base {
int common_id;
}
void dispatch_packet(void *packet) {
int common_id = ( (packet_base *)packet )->common_id;
switch(common_id) {...}
}
void test() {
packet_sample_t packet = {.common_id = 10, ...};
dispatch_packet((void *) &packet); //this function should retrieve `common_id`
packet_other_t other = {.common_id = 1};
dispatch_packet((void *) &other); // again with another packet
}
我对 C 语言不是很熟悉,我真的不知道我该怎么做。但简单来说,我希望能够将一个数据包投射到它的packet_base,它们共享一个公共变量。
编辑:示例中有更多详细信息
您可以使用union
将不同类型的数据聚合到一个结构中
struct packet1_t
{
// Packet1 specific data
......
}
struct packet2_t
{
// Packet2 specific data
......
}
struct packet_t
{
int common_id;
union
{
struct packet1_t packet1;
struct packet2_t packet2;
......
}
} packet;
现在,您可以根据 ID 从联合中选择正确的类型:
int do_something_with_packet(packet_t packet)
{
switch (packet.common_id)
{
case 1:
do_something_with_packet1(packet.packet1);
break;
case 2:
do_something_with_packet2(packet.packet2);
break;
..................
}
....
}
你的技术是有效的。有 a number of ways to do struct inheritance in C, and this is one of them. 21st Century C might be a good read for you as well as Object-Oriented Programming with ANSI C.
您在声明和使用您的结构和类型时遇到了问题。让我们看看这个。
struct packet_base {
int common_id;
};
它的类型是 struct packet_base
。如果要声明指向此类型的指针,则需要编写 struct packet_base *packet
。如果你想转换这种类型的变量,它是 (struct packet_base *)thing
.
这很烦人,因此您通常使用 typedef
为结构声明一个类型别名。语法是 typedef <type> <alias>
typedef struct {
int common_id;
} packet_base_t;
这表示类型 struct { int common_id; }
是 packet_base_t
的别名。现在您可以使用 packet_base_t
作为类型。 packet_base_t *packet
声明一个指针并 (packet_base_t *)thing
转换。
修复后,再加上一些小错误,它就可以工作了。请参阅 What is the difference between char array vs char pointer in C? 了解 char *data
与 char data[]
。
typedef struct {
int common_id;
int some;
char *data;
float foo;
} packet_sample_t;
typedef struct {
int common_id;
} packet_base_t;
void dispatch_packet(void *arg) {
// It's simpler to cast to a new variable once then to muck
// up the code with casts.
packet_base_t *packet = (packet_base_t *)arg;
int common_id = packet->common_id;
printf("id: %d\n", common_id);
}