1

私はこの問題に関してCでのみ働いています。

私は2つの関数プロトタイプを持っています:

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のテスト関数はまだ作成されていません。

これは、上記の2つの関数のコードです。

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;
    }
}
4

2 に答える 2

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
      ...
}

共通部分を抽出する方法がわからない場合は、両方の関数のコードをもう少し投稿してください。

于 2012-07-24T07:21:33.357 に答える
0

関数ポインタをキャストすることは間違いなくノーノーです。代わりに、構造体へのポインタを受け入れる中間関数型を使用してください。または、union-type-tagを最初のメンバーとするunion引数。

中間関数(「実際の」関数ごとに1つ)は、構造体から正しい引数を抽出し、それらを正しい関数に渡す必要があります。

于 2012-07-24T07:21:29.067 に答える