Common Routine To Call (Almost) Identical Functions

Discussion in 'C Programming' started by gamename, Apr 28, 2007.

  1. gamename

    gamename Guest

    Hi,

    I have 2 vendor libraries. One is for transmitting, the other
    receiving data. Virtually all of the functions in either lib are
    almost exactly alike in the way they're called. The only external
    difference is the name has an "R" or an "S" in it.

    ex
    fooSGetBytes(bufa, buftemp);
    fooRGetBytes(bufa, buftemp);

    Several of my own support routines have logic on the send and receive
    side that are also identical except that they're calling "R" functions
    or "S" functions.

    Is there any way to have 1 routine that calls either the "S" or "R"
    functions depending on a parm passed by the user? Otherwise, I have
    dozens and dozens of situations like this:

    if(send)
    fooSGetBytes()
    else
    fooRGetBytes()

    In short, I would rather have something like

    fnptr = fooSGetBytes
    ....lotsa code...
    fptr()

    Any ideas?

    Thanks,
    -T
    gamename, Apr 28, 2007
    #1
    1. Advertising

  2. gamename

    Eric Sosman Guest

    gamename wrote:
    > Hi,
    >
    > I have 2 vendor libraries. One is for transmitting, the other
    > receiving data. Virtually all of the functions in either lib are
    > almost exactly alike in the way they're called. The only external
    > difference is the name has an "R" or an "S" in it.
    >
    > ex
    > fooSGetBytes(bufa, buftemp);
    > fooRGetBytes(bufa, buftemp);
    >
    > Several of my own support routines have logic on the send and receive
    > side that are also identical except that they're calling "R" functions
    > or "S" functions.
    >
    > Is there any way to have 1 routine that calls either the "S" or "R"
    > functions depending on a parm passed by the user? Otherwise, I have
    > dozens and dozens of situations like this:
    >
    > if(send)
    > fooSGetBytes()
    > else
    > fooRGetBytes()
    >
    > In short, I would rather have something like
    >
    > fnptr = fooSGetBytes
    > ...lotsa code...
    > fptr()


    Why "something like" instead of "something exactly like?"
    That is, a function pointer seems the perfect solution to your
    problem. Or perhaps a struct containing several function
    pointers, if you need to call several "related" functions:

    struct funcFamily {
    someType (*getBytes)(someArgs);
    typeSome (*putBytes)(otherArgs);
    ...
    };

    const struct funcFamily SFuncs = {
    fooSGetBytes, fooSPutBytes, ... };
    const struct funcFamily RFuncs = {
    fooRGetBytes, fooRPutBytes, ... };

    ...
    myFunc(&SFuncs);
    ...
    myFunc(&RFuncs);
    ...

    void myFunc(const struct funcFamily *fam) {
    ...
    fam->getBytes(...);
    ...
    fam->putBytes(...);
    ...
    }

    The fundamental assumption here is that the corresponding
    pairs of S and R functions really are *identical* in their
    argument lists and return types. If they aren't, I don't see
    how you can avoid tests at the call sites.

    --
    Eric Sosman
    lid
    Eric Sosman, Apr 28, 2007
    #2
    1. Advertising

  3. "gamename" <> wrote in message
    news:...
    > Hi,
    >
    > I have 2 vendor libraries. One is for transmitting, the other
    > receiving data. Virtually all of the functions in either lib are
    > almost exactly alike in the way they're called. The only external
    > difference is the name has an "R" or an "S" in it.
    >
    > ex
    > fooSGetBytes(bufa, buftemp);
    > fooRGetBytes(bufa, buftemp);
    >
    > Several of my own support routines have logic on the send and receive
    > side that are also identical except that they're calling "R" functions
    > or "S" functions.
    >
    > Is there any way to have 1 routine that calls either the "S" or "R"
    > functions depending on a parm passed by the user? Otherwise, I have
    > dozens and dozens of situations like this:
    >
    > if(send)
    > fooSGetBytes()
    > else
    > fooRGetBytes()
    >
    > In short, I would rather have something like
    >
    > fnptr = fooSGetBytes
    > ...lotsa code...
    > fptr()
    >

    /*
    send or receive data
    Parmas: data - buffer for return on send
    len - number of bytes to send
    mode = 0 = receive, 1 = send
    Returns: 0 on success, -1 on fail
    */
    int talk(void *data, int len, int mode)
    {
    if(mode)
    res = SGetBytes(data, len);
    else
    res = RGetBytes(data, len);
    if(res != len)
    return -1;
    return 0;
    }

    You might want to take more drastic action on fail, such as aborting the
    program, if that makes sense for your application. Also if the interface to
    your SGetBytes type functions is a bit fiddly you might want to put the
    iritating bits into the function start - eg if buffers have to be aligned
    and a multiple of 8 bytes you could use a temporary allocated in the
    function, giving a clean interface to your calling code.
    --
    Free games and programming goodies.
    http://www.personal.leeds.ac.uk/~bgy1mm
    Malcolm McLean, Apr 28, 2007
    #3
  4. gamename

    jaysome Guest

    On 28 Apr 2007 06:44:44 -0700, gamename <>
    wrote:

    >Hi,
    >
    >I have 2 vendor libraries. One is for transmitting, the other
    >receiving data. Virtually all of the functions in either lib are
    >almost exactly alike in the way they're called. The only external
    >difference is the name has an "R" or an "S" in it.
    >
    >ex
    >fooSGetBytes(bufa, buftemp);
    >fooRGetBytes(bufa, buftemp);
    >
    >Several of my own support routines have logic on the send and receive
    >side that are also identical except that they're calling "R" functions
    >or "S" functions.
    >
    >Is there any way to have 1 routine that calls either the "S" or "R"
    >functions depending on a parm passed by the user? Otherwise, I have
    >dozens and dozens of situations like this:
    >
    >if(send)
    > fooSGetBytes()
    >else
    > fooRGetBytes()
    >
    >In short, I would rather have something like
    >
    >fnptr = fooSGetBytes
    >...lotsa code...
    >fptr()
    >
    >Any ideas?
    >
    >Thanks,
    >-T


    Consider using function pointers. Here is an example that should get
    you going:

    #include <assert.h>
    #include <stdio.h>

    #define MAX_TEMPBUF_SIZE 256

    typedef enum
    {
    TX,
    RX,
    NUM_DIRECTIONS
    } direction_enum;

    typedef void (*tx_rx_function_type)
    (
    const char *bufa,
    char *buftemp
    );

    static void exucute_function
    (
    direction_enum direction,
    const char *bufa,
    char *buftemp
    );
    static void fooSGetBytes(const char *bufa, char *buftemp);
    static void fooRGetBytes(const char *bufa, char *buftemp);

    static const tx_rx_function_type TX_RX_FUNCS[NUM_DIRECTIONS] =
    {
    fooSGetBytes,
    fooRGetBytes
    };

    int main(void)
    {
    int ii;
    const char *BUFS[NUM_DIRECTIONS] =
    {"This is the TX buf.", "This is the RX buf."};
    char tempbuf[MAX_TEMPBUF_SIZE];
    for ( ii = 0; ii < NUM_DIRECTIONS; ii++ )
    {
    /* wrapped in a function */
    exucute_function(TX, BUFS[ii], tempbuf);
    /* called directly */
    TX_RX_FUNCS[ii](BUFS[ii], tempbuf);
    }

    /* uncomment the following to fire off an assert. */
    /*exucute_function(NUM_DIRECTIONS, BUFS[0], tempbuf);*/

    return 0;
    }

    static void exucute_function
    (
    direction_enum direction,
    const char *bufa,
    char *buftemp
    )
    {
    assert((direction == TX) || (direction == RX));
    TX_RX_FUNCS[direction](bufa, buftemp);
    }

    static void fooSGetBytes(const char *bufa, char *buftemp)
    {
    printf
    (
    "fooSGetBytes() called with arguments bufa=%p buftemp=%p\n",
    (void*)bufa,
    (void*)buftemp
    );

    printf("bufa string is \"%s\"\n", bufa);
    }

    static void fooRGetBytes(const char *bufa, char *buftemp)
    {
    printf
    (
    "fooRGetBytes() called with arguments bufa=%p buftemp=%p\n",
    (void*)bufa,
    (void*)buftemp
    );
    printf("bufa string is \"%s\"\n", bufa);
    }

    Best reagards
    --
    jay
    jaysome, Apr 29, 2007
    #4
  5. On 28 Apr 2007 06:44:44 -0700, gamename <>
    wrote:

    >Hi,
    >
    >I have 2 vendor libraries. One is for transmitting, the other
    >receiving data. Virtually all of the functions in either lib are
    >almost exactly alike in the way they're called. The only external
    >difference is the name has an "R" or an "S" in it.
    >
    >ex
    >fooSGetBytes(bufa, buftemp);
    >fooRGetBytes(bufa, buftemp);
    >
    >Several of my own support routines have logic on the send and receive
    >side that are also identical except that they're calling "R" functions
    >or "S" functions.
    >
    >Is there any way to have 1 routine that calls either the "S" or "R"
    >functions depending on a parm passed by the user? Otherwise, I have
    >dozens and dozens of situations like this:
    >
    >if(send)
    > fooSGetBytes()
    >else
    > fooRGetBytes()


    You could use an array of function pointers and pass the array index
    to your function which would then call the library function using the
    specified element of the array.

    /* return type */ (*fooptr[]) (/*parameter types*/) =
    {fooRGetBytes, fooSGetBytes};

    fooptr[send]();

    >
    >In short, I would rather have something like
    >
    >fnptr = fooSGetBytes
    >...lotsa code...
    >fptr()



    Remove del for email
    Barry Schwarz, Apr 29, 2007
    #5
  6. gamename

    Guest

    On 28 Apr, 14:44, gamename <> wrote:
    > Hi,
    >
    > I have 2 vendor libraries. One is for transmitting, the other
    > receiving data. Virtually all of the functions in either lib are
    > almost exactly alike in the way they're called. The only external
    > difference is the name has an "R" or an "S" in it.
    >
    > ex
    > fooSGetBytes(bufa, buftemp);
    > fooRGetBytes(bufa, buftemp);
    >
    > Several of my own support routines have logic on the send and receive
    > side that are also identical except that they're calling "R" functions
    > or "S" functions.
    >
    > Is there any way to have 1 routine that calls either the "S" or "R"
    > functions depending on a parm passed by the user? Otherwise, I have
    > dozens and dozens of situations like this:


    If you're wanting to write pairs of new functions which are identical
    apart from which of the -S- and -R- functions they call, then you
    could try something along the lines of the following:

    macmain.c:

    #define name(before, after) three(before, letter, after)
    #define three(before, let, after) join(before, let, after)
    #define join(before, let, after) before##let##after

    #define letter R

    #include "macsub.c"

    #define letter S

    #include "macsub.c"

    macsub.c:

    int name(Test, main) (void) {
    name(Test, sub1) ();
    name(Test, sub2) ();
    }

    These will compile to give:

    int TestRmain (void) {
    TestRsub1 ();
    TestRsub2 ();
    }

    int TestSmain (void) {
    TestSsub1 ();
    TestSsub2 ();
    }

    This may of course not be what you want, but it's a suggestion.
    Hope it helps.
    Paul.
    , May 3, 2007
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Luminari
    Replies:
    23
    Views:
    789
    Wings
    Feb 11, 2007
  2. David. E. Goble
    Replies:
    9
    Views:
    464
    David. E. Goble
    Feb 2, 2005
  3. IanT

    How to handle common/routine exceptions?

    IanT, Jun 9, 2004, in forum: ASP .Net Web Services
    Replies:
    2
    Views:
    195
  4. Luminari
    Replies:
    0
    Views:
    101
    Luminari
    Feb 8, 2007
  5. lorlarz
    Replies:
    11
    Views:
    167
    lorlarz
    Sep 9, 2008
Loading...

Share This Page