如何解决哪种编码策略/架构布局在 C 中以最少的努力实现了编译时多态性?
有一个源文件andy_web.c
,它以程序的形式管理网页相关的东西,叫做andy_web.cgi
,由lighttpd
调用。
简而言之,如果收到get=setting
,andy_web.cgi
会通过调用函数andy_cfg_retrive_height
从andy的配置文件中获取高度,并在页面中显示;如果收到 post=setting
,andy_web.cgi
将从 lighttpd
获取高度并通过调用函数 andy_cfg_set_height
将其设置到配置文件中。
/*web_api.h*/
#ifndef WEB_API_H
#define WEB_API_H
#define MAX_NAME_LEN 128
#define MAX_VALUE_LEN 128
struct web_http_nv
{
char name[MAX_NAME_LEN];
char value[MAX_VALUE_LEN];
};
#define MAX_NAME_VALUE_LEN 512
typedef struct web_t web_t;
struct web_t
{
struct web_http_nv nameval[MAX_NAME_VALUE_LEN]; /* (name,value) pair from web */
int nv_ct; /* (name,value) pair count */
};
void web_get(web_t* web); /* get (name,value) pair from web */
#endif
/*andy_web.c*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "web_api.h"
#include "andy_web.h"
static void printMsg(char *msg)
{
fprintf(stderr,"%s\n",msg);
}
static web_t web = {0};
static void andy_web_page_show(void);
static int andy_web_page_setting_check_then_save(char Msg[],uint16_t MsgSize);
int main(void)
{
web_get(&web);
const uint8_t METHOD = web.nv_ct - 1;
if (!strcmp(web.nameval[METHOD].name,"get"))
{
if (!strcmp(web.nameval[METHOD].value,"setting"))
{
andy_web_page_show();
}
goto DONE;
}
char Msg[100] = {0};
if (!strcmp(web.nameval[METHOD].name,"post"))
{
if (!strcmp(web.nameval[METHOD].value,"setting"))
{
if (andy_web_page_setting_check_then_save(Msg,sizeof(Msg)) == -1)
{
goto SETTING_CHECK_ERROR;
}
}
andy_web_page_show();
}
DONE:
return 0;
SETTING_CHECK_ERROR:
printMsg(Msg);
return -1;
}
#define MIN_HEIGHT 150
#define MAX_HEIGHT 250
static void andy_web_page_show(void)
{
printf("Content-Type: text/html\n\n");
printf("<html>\n");
printf("<head>\n");
printf("<Meta http-equiv=\"Content-Type\" content=\"text/html;\" />\n");
printf("<title>andy Setting</title>\n");
printf("</head>\n");
printf("<body>\n");
printf("<fieldset>\n");
printf("<legend>andy Setting</legend>\n");
printf("<form name=\"andyPage\" method=\"post\" action=\"/cgi-bin/andy_web.cgi\" >\n");
printf(" <table id=\"table1\" border=\"0\" cellpadding=\"1\" cellspacing=\"1\">\n");
uint8_t height = 0;
if (andy_config_retrive_height(&height) != -1)
{
printf(" <tr>\n");
printf(" <td height=\"20\" width=\"150\" style=\"padding-left:10px\">andy height</td>\n");
printf(" <td height=\"20\" ><input type=\"text\" name=\"height\" style=\"width: 100;\" value=\"%d\" />(%d~%d)</td>\n",height,MIN_HEIGHT,MAX_HEIGHT);
printf(" </tr>\n");
}
printf(" </table>\n");
printf(" <p align=\"center\">\n");
printf(" <input type=\"submit\" value=\" Update \" />\n");
printf(" <input type=\"hidden\" name=\"post\" value=\"setting\" />\n");
printf(" </p>\n");
printf("</form>\n");
printf("</body>\n");
printf("</html>\n");
}
static int andy_web_page_setting_check_then_save(char Msg[],uint16_t MsgSize)
{
int count = 0;
for (; count < web.nv_ct-1; count++)
{
if (!strcmp(web.nameval[count].name,"height"))
{
uint8_t height = atoi(web.nameval[count].value);
if ((height < MIN_HEIGHT) || (height >= MAX_HEIGHT))
{
snprintf(Msg,MsgSize,"height <%d> should be between %d and %d",MAX_HEIGHT);
return -1;
}
andy_config_set_height(height);
}
}
return 0;
}
让我们假设一个场景,在系统上存储配置文件的方法从一开始就决定了,一旦系统运行就不会改变。换句话说,只要决定使用一种方法(例如 INI 文件)来存储配置文件,就不可能动态更改该方法,除非系统上安装了新映像。图像中总是只有一种方法。
在许多实现中,例如 INI 文件、二进制文件等,一旦构建映像,andy_cfg_set_height
和 andy_cfg_retrive_height
只有一种选择。
如果我被要求更改存储配置文件的方法,我会尝试找到最小化维护成本的最佳方法。
以下是我的解决方案。它调用一个命令 iniparser
,我根据它的 open source 为自己编写,通过调用 andy.ini
/{{1} 来设置/检索 andy 的高度到/从 system
}. iniparser 本身基本上解析 ini 文件并提供在 C 级别读取/写入文本文件的能力。
虽然我不愿意使用这种将实现写在头文件中的方法,但它似乎是实现编译时多态的最有效方法,因为在新的应用存储配置文件的方法。假设我将 popen
作为一种实现,将 andy_web.h
作为另一种实现。通过这种方法,如果我选择使用该实现,我可以将 andy_web_method_1.h
复制并粘贴到 andy_web_method_2.h
中。
andy_web_method_1.h
我想知道
-
什么情况下适合(或不适合)这种方法?
-
有其他替代品吗?
-
如果是这样,你会在什么考虑下采用它?怎么办?
顺便说一下,我想让 this relevant question 获得更多关注。但是,我不知道在其他帖子上宣传其他问题是否合法。如果不允许,请告诉我。
解决方法
通过函数/方法重载,您将需要最少的努力来实现编译时多态性
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。