Best method for creating function "templates"

Discussion in 'C Programming' started by Spiros Bousbouras, Feb 25, 2011.

  1. I'm writing a library where on error the library functions are supposed
    to call a function with prototype
    unsigned long error_handler(unsigned long , unsigned long)
    which should be supplied by the user. The question is what should the
    library header contain to make it as easy as possible for the user to
    declare or define such functions or pointers to such functions or casts
    to pointers to such functions etc. and that if the prototype for an
    error handler changes the user will have to do as few modifications as
    possible to his source.

    At present the header contains

    typedef unsigned long (*error_handler_type)(unsigned long , unsigned long)
    #define error_handler_def(foo_name , var1 , var2) \
    unsigned long foo_name(unsigned long var_name1 , \
    unsigned long var_name2)

    so for a declaration the user can do

    error_handler_type my_error_handler ;

    and for a definition

    error_handler_def(my_error_handler , foo_id , err_id) {
    ...code...
    }

    Is there a better way ?

    --
    Some of it is kind of confidential but we run a mixture of real
    machines, VMs and use mainly Ubuntu for Linux development but of course
    Windows for all the malware stuff.
    Jerome Segura
    Spiros Bousbouras, Feb 25, 2011
    #1
    1. Advertising

  2. On Fri, 25 Feb 2011 22:58:02 GMT
    Spiros Bousbouras <> wrote:
    > I'm writing a library where on error the library functions are supposed
    > to call a function with prototype
    > unsigned long error_handler(unsigned long , unsigned long)
    > which should be supplied by the user. The question is what should the
    > library header contain to make it as easy as possible for the user to
    > declare or define such functions or pointers to such functions or casts
    > to pointers to such functions etc. and that if the prototype for an
    > error handler changes the user will have to do as few modifications as
    > possible to his source.
    >
    > At present the header contains
    >
    > typedef unsigned long (*error_handler_type)(unsigned long , unsigned long)


    Sorry , that should be
    typedef unsigned long error_handler_type(unsigned long , unsigned long) ;

    > #define error_handler_def(foo_name , var1 , var2) \
    > unsigned long foo_name(unsigned long var_name1 , \
    > unsigned long var_name2)
    >
    > so for a declaration the user can do
    >
    > error_handler_type my_error_handler ;
    >
    > and for a definition
    >
    > error_handler_def(my_error_handler , foo_id , err_id) {
    > ...code...
    > }
    >
    > Is there a better way ?
    Spiros Bousbouras, Feb 25, 2011
    #2
    1. Advertising

  3. On Feb 25, 5:11 pm, Spiros Bousbouras <> wrote:
    > On Fri, 25 Feb 2011 22:58:02 GMT
    >
    > Spiros Bousbouras <> wrote:
    > > I'm writing a library where on error the library functions are supposed
    > > to call a function with prototype
    > > unsigned long error_handler(unsigned long , unsigned long)
    > > which should be supplied by the user. The question is what should the
    > > library header contain to make it as easy as possible for the user to
    > > declare or define such functions or pointers to such functions or casts
    > > to pointers to such functions etc. and that if the prototype for an
    > > error handler changes the user will have to do as few modifications as
    > > possible to his source.

    >


    What about parameter names? If the user has to supply a function to
    process these values, it might help to know what they're for.
    luser- -droog, Feb 26, 2011
    #3
  4. On Fri, 25 Feb 2011 22:22:28 -0800 (PST)
    luser- -droog <> wrote:
    > On Feb 25, 5:11=A0pm, Spiros Bousbouras <> wrote:
    > > On Fri, 25 Feb 2011 22:58:02 GMT
    > >
    > > Spiros Bousbouras <> wrote:
    > > > I'm writing a library where on error the library functions are supposed
    > > > to call a function with prototype
    > > > unsigned long error_handler(unsigned long , unsigned long)
    > > > which should be supplied by the user. The question is what should the
    > > > library header contain to make it as easy as possible for the user to
    > > > declare or define such functions or pointers to such functions or casts
    > > > to pointers to such functions etc. and that if the prototype for an
    > > > error handler changes the user will have to do as few modifications as
    > > > possible to his source.

    > >

    >
    > What about parameter names? If the user has to supply a function to
    > process these values, it might help to know what they're for.


    The documentation for the library will explain what the parameters are
    for , there's no need to include the information in the header. But in
    any case my actual source does have a comment which explains what the
    parameters are for.
    Spiros Bousbouras, Feb 26, 2011
    #4
  5. Spiros Bousbouras

    Jorgen Grahn Guest

    On Fri, 2011-02-25, Spiros Bousbouras wrote:
    > I'm writing a library where on error the library functions are supposed
    > to call a function with prototype
    > unsigned long error_handler(unsigned long , unsigned long)
    > which should be supplied by the user. The question is what should the
    > library header contain to make it as easy as possible for the user to
    > declare or define such functions or pointers to such functions or casts
    > to pointers to such functions etc. and that if the prototype for an
    > error handler changes the user will have to do as few modifications as
    > possible to his source.

    ....
    > Is there a better way ?


    Not an answer, but it's a good idea to also provide a void* for
    user-supplied data (unless one of those two unsigned longs serve that
    purpose).

    It can be really frustrating to get a callback, but not being able to
    *do* anything useful because you don't have access to your own data
    structures. That tends to end up with you making all your data
    structures (reachable through) global variables -- ugh.

    /Jorgen

    --
    // Jorgen Grahn <grahn@ Oo o. . .
    \X/ snipabacken.se> O o .
    Jorgen Grahn, Feb 28, 2011
    #5
  6. On 28 Feb 2011 14:45:50 GMT
    Jorgen Grahn <> wrote:
    > On Fri, 2011-02-25, Spiros Bousbouras wrote:
    > > I'm writing a library where on error the library functions are supposed
    > > to call a function with prototype
    > > unsigned long error_handler(unsigned long , unsigned long)
    > > which should be supplied by the user. The question is what should the
    > > library header contain to make it as easy as possible for the user to
    > > declare or define such functions or pointers to such functions or casts
    > > to pointers to such functions etc. and that if the prototype for an
    > > error handler changes the user will have to do as few modifications as
    > > possible to his source.

    > ...
    > > Is there a better way ?

    >
    > Not an answer, but it's a good idea to also provide a void* for
    > user-supplied data (unless one of those two unsigned longs serve that
    > purpose).


    Yes. I posted a simplified version here but my actual code passes 4
    parameters , the first 3 are unsigned long for module ID , function ID
    and error ID respectively and the last void* for the reason you say.

    > It can be really frustrating to get a callback, but not being able to
    > *do* anything useful because you don't have access to your own data
    > structures. That tends to end up with you making all your data
    > structures (reachable through) global variables -- ugh.
    Spiros Bousbouras, Feb 28, 2011
    #6
  7. Spiros Bousbouras

    Dr Nick Guest

    Jorgen Grahn <> writes:

    > Not an answer, but it's a good idea to also provide a void* for
    > user-supplied data (unless one of those two unsigned longs serve that
    > purpose).
    >
    > It can be really frustrating to get a callback, but not being able to
    > *do* anything useful because you don't have access to your own data
    > structures. That tends to end up with you making all your data
    > structures (reachable through) global variables -- ugh.


    Yes yes yes. One of the most important lessons I've learnt in the last
    few years. Sooner or later you end up going back and hacking the code
    to put that user data pointer in, so you might as well put it there in
    the first place. Another thing the standard library didn't necessarily
    get completely right and which was too easy to slavishly copy.
    --
    Online waterways route planner | http://canalplan.eu
    Plan trips, see photos, check facilities | http://canalplan.org.uk
    Dr Nick, Mar 1, 2011
    #7
    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. Fred
    Replies:
    1
    Views:
    597
    Neredbojias
    Sep 26, 2005
  2. JKop
    Replies:
    3
    Views:
    468
  3. BigMan
    Replies:
    1
    Views:
    434
  4. recover
    Replies:
    2
    Views:
    800
    recover
    Jul 25, 2006
  5. Chris
    Replies:
    7
    Views:
    316
    Pavel
    Aug 8, 2008
Loading...

Share This Page