2012-07-24 182 views
1

我僅在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

回答

3

由於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

0

鑄造函數指針是一個明確的禁忌。使用接受指向結構的指針的中間函數類型。或者使用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

相關問題