我有一台设备。它需要命令。我得到了结果,并希望将它们放到更有用的形式中。
示例:
issue_command()
应该将一个结构作为请求和指向结果结构的指针...但结构可以是我传递的任何内容。所有人都有大约50个结构。
issue_command(read_request, &result_struct);
我觉得C不能这样做,我无法想出一个可能的解决方案(它是我的程序中唯一未完成的方面)。
用外行人的话说,我想传递一个命令结构,该结构被炸成设备,结果结构参数从字节结果中传递memcpy()
'。
答案 0 :(得分:0)
这是一个做我认为你想要的示例程序:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
/* Enumeration, structs, and union for requests */
enum request_type {
REQUEST_ONE,
REQUEST_TWO
};
struct request_one {
int something;
char data[10];
};
struct request_two {
double something_else;
char data[20];
};
struct request {
enum request_type type;
union {
struct request_one one;
struct request_two two;
} request_struct;
};
/* Enumeration, structs, and union for responses */
enum response_type {
RESPONSE_ONE,
RESPONSE_TWO
};
struct response_one {
char data[10];
};
struct response_two {
char data[20];
};
struct response {
enum response_type type;
union {
struct response_one one;
struct response_two two;
} response_struct;
};
/* Constructor functions for request structs */
struct request * make_request_one(const int something,
char * data) {
struct request * new_request = malloc(sizeof *new_request);
if ( !new_request ) {
perror("Couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_request->type = REQUEST_ONE;
new_request->request_struct.one.something = something;
strcpy(new_request->request_struct.one.data, data);
return new_request;
}
struct request * make_request_two(const double something_else,
char * data) {
struct request * new_request = malloc(sizeof *new_request);
if ( !new_request ) {
perror("Couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_request->type = REQUEST_TWO;
new_request->request_struct.two.something_else = something_else;
strcpy(new_request->request_struct.two.data, data);
return new_request;
}
/* Constructor functions for response structs */
struct response * make_response_one(char * data) {
struct response * new_response = malloc(sizeof *new_response);
if ( !new_response ) {
perror("Couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_response->type = RESPONSE_ONE;
strcpy(new_response->response_struct.one.data, data);
return new_response;
}
struct response * make_response_two(char * data) {
struct response * new_response = malloc(sizeof *new_response);
if ( !new_response ) {
perror("Couldn't allocate memory");
exit(EXIT_FAILURE);
}
new_response->type = RESPONSE_TWO;
strcpy(new_response->response_struct.two.data, data);
return new_response;
}
/* Issue command function */
struct response * issue_command(struct request * request) {
struct response * response;
switch ( request->type ) {
case REQUEST_ONE:
response = make_response_one("resp 1");
break;
case REQUEST_TWO:
response = make_response_two("response 2 stuff");
break;
default:
assert(0);
}
return response;
}
int main(void) {
/* Call issue_command() with request and response one */
struct request * req1 = make_request_one(666, "req 1");
struct response * resp1 = issue_command(req1);
printf("Request: %s, Response: %s\n",
req1->request_struct.one.data,
resp1->response_struct.one.data);
free(req1);
free(resp1);
/* Call issue_command() with request and response two */
struct request * req2 = make_request_two(3.14159, "request 2 stuff");
struct response * resp2 = issue_command(req2);
printf("Request: %s, Response: %s\n",
req2->request_struct.two.data,
resp2->response_struct.two.data);
free(req2);
free(resp2);
return 0;
}
和输出:
paul@local:~/src/sandbox$ ./reqresp
Request: req 1, Response: resp 1
Request: request 2 stuff, Response: response 2 stuff
paul@local:~/src/sandbox$
正如您所看到的,issue_command()
函数通过单个输入参数有效地接受两种不同类型的结构,并使用单个返回值有效地返回两种不同类型的结构。这是通过在两种情况下将不同的结构包装在一个联合中来实现的,但是你可以通过void
指针实现类似的结果,并且实际上传递和返回完全不同的结构(而不是包含不同结构的联合的单个结构) )。
我在issue_command()
所做的一切都是阅读类型并构建适当的回复,但在switch
区块中,一旦您确定了自己的类型,就可以做你喜欢的事,访问请求的个别成员,或memcpy()
整个事情,或其他什么。同样,对于回复,一旦您知道您的请求类型,您就可以阅读并填写您喜欢的回复成员。