将多态函数作为参数传递给另一个函数C

问题描述:

我仅在C中处理此问题。将多态函数作为参数传递给另一个函数C

我有两个函数原型:

int pkg_permserver(const char *service, const char *protocol, int backlog, void (*errlog) (char *msg))

int pkg_permserver_ip(const char *ipOrHostname, const char *service, const char *protocol, int backlog, void (*errlog)(char *msg))

和下面的代码段:

int test_permserv(char *port) { 
    int return_val; 
    int num_port; 
    char *chr_port; 
    int nr_test_passed=0; 
    chr_port = (char *) bu_malloc(8 * sizeof(char), "port string"); 

    printf("TESTING PKG_PERMSERVER.....\n PORT PARAMETER TEST: \n"); 

    printf("TESTING VALID PORT...\n"); 
    return_val = pkg_permserver(port ,"tcp", 0, 0); 
    display(return_val,1,&nr_test_passed); 

    printf("TESTING INVALID PORT...\n"); 
    num_port = -1; 
    sprintf(chr_port, "%d", num_port); 
    return_val = pkg_permserver(chr_port ,"tcp", 0, 0); 
    display(return_val,0,&nr_test_passed); 
} 

我写一个测试单元。我需要测试每个函数的每个参数(有效/无效)。

我无法修改上述功能。 pkg_permserver和pkg_permserver_ip具有完全相同的参数,但pkg_permserver_ip另外具有IpOrHostname。

如果我要写另一个函数“test_permserver_ip”我不想复制 - 粘贴test_permserver中的部分(因为参数是相同的)。我的脑海里有什么像int test_permserver(char * port,int which_function);

我想避免复制test_permserver_ip的相同代码(对于与test_permserver相同的参数) pkg_permserver_ip的测试功能尚未写入。

这是上述两种功能的代码:

int pkg_permserver(const char *service, const char *protocol, int backlog, void (*errlog) (char *msg)) 
{ 
    struct in_addr iface; 
    iface.s_addr = INADDR_ANY; 
    return _pkg_permserver_impl(iface, service, protocol, backlog, errlog); 
} 


int 
pkg_permserver_ip(const char *ipOrHostname, const char *service, const char *protocol, int backlog, void (*errlog)(char *msg)) 
{ 
    struct hostent* host; 
    struct in_addr iface; 
    /* if ipOrHostname starts with a number, it's an IP */ 
    if (ipOrHostname) { 
    if (ipOrHostname[0] >= '0' && ipOrHostname[0] <= '9') { 
     iface.s_addr = inet_addr(ipOrHostname); 
    } else { 
     /* XXX gethostbyname is deprecated on Windows */ 
     host = gethostbyname(ipOrHostname); 
     iface = *(struct in_addr*)host->h_addr; 
    } 
    return _pkg_permserver_impl(iface, service, protocol, backlog, errlog); 
    } else { 
    _pkg_perror(errlog, "pkg: ipOrHostname cannot be NULL"); 
    return -1; 
    } 
} 
+3

你是否考虑过在pkg_permserver_ip中调用pkg_permserver,完成'专门的东西'之后?我不认为将一个函数指针投射到一个void指针可以工作......实际上,我很确定它没有。 – ATaylor 2012-07-24 07:08:35

+0

但是你打算如何将'pkg_permserver_ip'作为额外的参数传给你?如果您必须准备额外的参数,那意味着代码不是完整的复制粘贴。 – AnT 2012-07-24 07:15:31

+1

您正在使用不同端口(arg1)调用pkg_permserver()两次。 pkg_permserver_ip()在哪里? – Jeyaram 2012-07-24 07:15:43

由于ATaylor说,单纯从两个功能中提取的共同的东西,并得到类似

int common_stuff_for_permserver(... all common params ...) 
{ 
    .... 
} 

int pkg_permserver(...) 
{ 
     /// nothing to add here 
     return common_stuff_for_permserver(... all params ...); 
} 

int pkg_permserver_ip(...) 
{ 
     /// check for errors from common stuff 
     if(!common_stuff_for_permserver(... all params ...)) { return 0; } 

     /// ip-specific stuff 
     ... 
} 

如果你不知道如何提取的公共部分,张贴一些更多的代码两种功能,我们”我会考虑一下。

+0

我认为解决方案比看起来更简单。 pkg_permserver和pkg_permserver_ip都调用_pkg_permserver_impl(iface,service,protocol,backlog,errlog);因此,如果我测试pkg_permserver的每个参数,然后仅测试pkg_permserver_ip的ipOrhostname参数,它仍然是一个完整的测试 – pAndrei 2012-07-24 07:31:12

铸造函数指针是一个明确的禁忌。使用接受指向结构的指针的中间函数类型。或者使用union-type-tag作为第一个成员的联合参数。

中间函数(一个用于每个“真实”函数)只需从结构中提取正确的参数并将它们传递给正确的函数。

+0

这两个函数调用相同的_pkg_permserver_impl(iface,service,protocol,backlog,errlog);简化事情,我会测试pkg_permserver的每个参数,然后为pkg_permserver_ip测试只有ipOrHostname参数 – pAndrei 2012-07-24 07:41:52