need addititional arg in given callback

Collapse
This topic is closed.
X
X
 
  • Time
  • Show
Clear All
new posts
  • Felix Kater

    #1

    need addititional arg in given callback

    Hi,

    in a given library I register callback functions with this function:

    bool set_callback(in t index, int (*callback_func tion)(long));

    I need the callback function to also pass the index which is, however,
    not (re-)passed by the callback function.

    Normally, I would just register callback functions for each
    index I need if the amount of callback functions was known at design
    time... But it isn't.

    Could someone help me find the right approach to solve that problem?

    Felix
  • Richard Bos

    #2
    Re: need addititional arg in given callback

    Felix Kater <f.kater2@gmx.n et> wrote:
    [color=blue]
    > in a given library I register callback functions with this function:
    >
    > bool set_callback(in t index, int (*callback_func tion)(long));
    >
    > I need the callback function to also pass the index which is, however,
    > not (re-)passed by the callback function.
    >
    > Normally, I would just register callback functions for each
    > index I need if the amount of callback functions was known at design
    > time... But it isn't.
    >
    > Could someone help me find the right approach to solve that problem?[/color]

    It's a quandary. You'd like closures for something like this, but you
    don't have those in C. A quick and dirty hack would be to use a
    file-scope (i.e., global, or if at all possible, file-local) variable,
    possibly with the aid of a helper function if you can't change the
    callback function itself.

    Richard

    Comment

    • Felix Kater

      #3
      Re: need addititional arg in given callback

      rlb@hoekstra-uitgeverij.nl (Richard Bos) wrote:
      [color=blue]
      > A quick and dirty hack would be to use a
      > file-scope (i.e., global, or if at all possible, file-local) variable,
      > possibly with the aid of a helper function[/color]

      Good to hear that there's a way, however, could you elaborate that a
      bit to me?

      Felix

      Comment

      • Keith Thompson

        #4
        Re: need addititional arg in given callback

        Felix Kater <f.kater2@gmx.n et> writes:[color=blue]
        > in a given library I register callback functions with this function:
        >
        > bool set_callback(in t index, int (*callback_func tion)(long));
        >
        > I need the callback function to also pass the index which is, however,
        > not (re-)passed by the callback function.
        >
        > Normally, I would just register callback functions for each
        > index I need if the amount of callback functions was known at design
        > time... But it isn't.[/color]

        If you can't change the type of the argument passed to the callback
        function, you could make its argument an index into a data structure
        from which it can retrieve as much information as you care to provide.

        The simplest such data structure, of course, is an array (presumably
        of structs or of pointers to structs). If you don't know in advance
        how many elements you'll need, allocate it dynamically and use
        realloc() as needed to expand it.

        --
        Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
        San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
        We must do something. This is something. Therefore, we must do this.

        Comment

        • Felix Kater

          #5
          Re: need addititional arg in given callback

          Keith Thompson <kst-u@mib.org> wrote:
          [color=blue]
          > If you can't change the type of the argument passed to the callback
          > function, you could make its argument an index into a data structure[/color]

          I'm afraid I didn't get the point:

          a. I can't re-use the long arg from the callback function as a pointer
          since this value (which is passed) has nothing to do with the index
          value I need inside the callback function and which I pass to the
          register function.

          b. If you ment to make an array of function pointers: How would I fill
          that with meaningfull pointers to functions which I would have to hard
          code anyway?

          Felix

          Comment

          • Keith Thompson

            #6
            Re: need addititional arg in given callback

            Felix Kater <f.kater2@gmx.n et> writes:[color=blue]
            > Keith Thompson <kst-u@mib.org> wrote:
            >[color=green]
            >> If you can't change the type of the argument passed to the callback
            >> function, you could make its argument an index into a data structure[/color]
            >
            > I'm afraid I didn't get the point:
            >
            > a. I can't re-use the long arg from the callback function as a pointer
            > since this value (which is passed) has nothing to do with the index
            > value I need inside the callback function and which I pass to the
            > register function.[/color]
            [snip]

            Sorry, I think I misunderstood the problem (I don't often use callback
            functions). I was thinking you could control the long value passed to
            the callback function, but obviously it's called by the library in a
            manner you can't control.

            The library provides:

            bool set_callback(in t index, int (*callback_func tion)(long));

            What does the long argument represent?

            (There may not be a good way to do what you want.)

            --
            Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
            San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
            We must do something. This is something. Therefore, we must do this.

            Comment

            • CBFalconer

              #7
              Re: need addititional arg in given callback

              Felix Kater wrote:[color=blue]
              >
              > in a given library I register callback functions with this
              > function:
              >
              > bool set_callback(in t index, int (*callback_func tion)(long));
              >
              > I need the callback function to also pass the index which is,
              > however, not (re-)passed by the callback function.
              >
              > Normally, I would just register callback functions for each
              > index I need if the amount of callback functions was known at
              > design time... But it isn't.
              >
              > Could someone help me find the right approach to solve that
              > problem?[/color]

              This has nothing to do with the portable standard C language, but
              deals with your particular system and installation. So find a
              newsgroup that deals with that system.

              --
              Chuck F (cbfalconer@yah oo.com) (cbfalconer@wor ldnet.att.net)
              Available for consulting/temporary embedded and systems.
              <http://cbfalconer.home .att.net> USE worldnet address!

              Comment

              • Keith Thompson

                #8
                Re: need addititional arg in given callback

                CBFalconer <cbfalconer@yah oo.com> writes:[color=blue]
                > Felix Kater wrote:[color=green]
                >> in a given library I register callback functions with this
                >> function:
                >>
                >> bool set_callback(in t index, int (*callback_func tion)(long));
                >>
                >> I need the callback function to also pass the index which is,
                >> however, not (re-)passed by the callback function.
                >>
                >> Normally, I would just register callback functions for each
                >> index I need if the amount of callback functions was known at
                >> design time... But it isn't.
                >>
                >> Could someone help me find the right approach to solve that
                >> problem?[/color]
                >
                > This has nothing to do with the portable standard C language, but
                > deals with your particular system and installation. So find a
                > newsgroup that deals with that system.[/color]

                I don't agree that the question is necessarily off-topic. He's using
                a particular system-specific library, and details about the workings
                of that library would certainly be off-topic, but there have already
                been several responses about possible solutions that depend only on
                the set_callback declaration he's shown us.

                It may turn out that the *solution* is either system-specific (and
                therefore off-topic) or nonexistent.

                --
                Keith Thompson (The_Other_Keit h) kst-u@mib.org <http://www.ghoti.net/~kst>
                San Diego Supercomputer Center <*> <http://users.sdsc.edu/~kst>
                We must do something. This is something. Therefore, we must do this.

                Comment

                • Felix Kater

                  #9
                  Re: need addititional arg in given callback

                  Keith Thompson <kst-u@mib.org> wrote:
                  [color=blue]
                  > It may turn out that the *solution* is either system-specific (and
                  > therefore off-topic) or nonexistent.[/color]

                  The more I ask people about that problem the more I believe there is no
                  clean solution: Since the only distinguishing information between the
                  callback functions the client programmer gets are the function pointers
                  itself I can only register different functions -- and, as I don't know
                  how many there will be necessary I don't see any way to do that in advance.

                  Felix

                  Comment

                  • E. Robert Tisdale

                    #10
                    Re: need addititional arg in given callback

                    Felix Kater wrote:
                    [color=blue]
                    > in a given library I register callback functions with this function:
                    >
                    > bool set_callback(in t index, int (*callback_func tion)(long));[/color]

                    Did you write this function?
                    What is the index argument used for?[color=blue]
                    >
                    > I need the callback function to also pass the index
                    > which is, however, not (re-)passed by the callback function.[/color]

                    What do you mean here?
                    Your *set_callback* function passes index
                    but your *callback* function does not?[color=blue]
                    >
                    > Normally, I would just register callback functions
                    > for each index [that] I need
                    > if the [number] of callback functions was known at design time...
                    > But it isn't.
                    >
                    > Could someone help me find the right approach to solve that problem?[/color]

                    What problem?
                    Try to elaborate a little more.
                    Show us an example.

                    Comment

                    • Richard Bos

                      #11
                      Re: need addititional arg in given callback

                      Felix Kater <f.kater2@gmx.n et> wrote:
                      [color=blue]
                      > rlb@hoekstra-uitgeverij.nl (Richard Bos) wrote:
                      >[color=green]
                      > > A quick and dirty hack would be to use a
                      > > file-scope (i.e., global, or if at all possible, file-local) variable,
                      > > possibly with the aid of a helper function[/color]
                      >
                      > Good to hear that there's a way, however, could you elaborate that a
                      > bit to me?[/color]

                      AFAICT, what you want is something like this:

                      int callback(long index)
                      {
                      return some_lookup[index];
                      }

                      which you can set up with

                      set_callback(&c allback, some_index);

                      and should then be called by the surrounding code (probably a library or
                      the OS API) like this:

                      callback(index) ;

                      whereas what this code actually does is this:

                      callback();

                      and you're required to set things up using

                      set_callback(&c allback);

                      with no provision for passing in the required index.

                      Is that impression of what you want right? If not, I'm sorry, I
                      misunderstood what you want. If it is, though, you could do this
                      instead:

                      long public_index;

                      int callback_helper (void)
                      {
                      return callback(public _index);
                      }

                      public_index=so me_index;
                      set_callback(&c allback_helper) ;

                      so that a call to the callback function will result in

                      callback_helper ();

                      which will fetch the index you wanted, and then call the original
                      callback function with that value.

                      Richard

                      Comment

                      • Felix Kater

                        #12
                        Re: need addititional arg in given callback

                        "E. Robert Tisdale" <E.Robert.Tisda le@jpl.nasa.gov > wrote:
                        [color=blue][color=green]
                        > > bool set_callback(in t index, int (*callback_func tion)(long));[/color]
                        >
                        > Did you write this function?[/color]

                        No, and I can't change it.

                        [color=blue]
                        > What is the index argument used for?[/color]

                        It's used for the logic inside the library. Think of a simple
                        assignment which hardware event is bound to what callback.
                        If this index was passed to/by the callback as an argument I would be
                        done...

                        [color=blue][color=green]
                        > > I need the callback function to also pass the index
                        > > which is, however, not (re-)passed by the callback function.[/color]
                        >
                        > What do you mean here?
                        > Your *set_callback* function passes index
                        > but your *callback* function does not?[/color]

                        Exactly. If the callback would pass the index I could just use one
                        callback function for all indexes and check the index what to do.
                        Without that I have to create callback functions for each index. That's
                        the problem...

                        More and more I think there is no general way out of this dilemma. I'll
                        try to contact the distributor of the libraray and ask if they could
                        pass the index argument with the next release.

                        Felix

                        Comment

                        • Felix Kater

                          #13
                          Re: need addititional arg in given callback

                          rlb@hoekstra-uitgeverij.nl (Richard Bos) wrote:
                          [color=blue]
                          > Is that impression of what you want right? If not, I'm sorry, I
                          > misunderstood what you want. If it is, though, you could do this
                          > instead:
                          >
                          > long public_index;
                          >
                          > int callback_helper (void)
                          > {
                          > return callback(public _index);
                          > }
                          >
                          > public_index=so me_index;
                          > set_callback(&c allback_helper) ;
                          >
                          > so that a call to the callback function will result in
                          >
                          > callback_helper ();
                          >
                          > which will fetch the index you wanted, and then call the original
                          > callback function with that value.[/color]


                          Thanks for that, Richard.
                          You didn't misunderstand me.

                          I realize now, however, that I didn't mention the fact clearly that I
                          have to register more than one callback function in the beginning
                          (rather than set and unset them) which will then be called at any time
                          in any order. So, I don't know when to set the public_index.

                          Felix

                          Comment

                          • Richard Bos

                            #14
                            Re: need addititional arg in given callback

                            Felix Kater <f.kater2@gmx.n et> wrote:
                            [color=blue]
                            > rlb@hoekstra-uitgeverij.nl (Richard Bos) wrote:
                            >[color=green]
                            > > Is that impression of what you want right? If not, I'm sorry, I
                            > > misunderstood what you want. If it is, though, you could do this
                            > > instead:
                            > >
                            > > long public_index;
                            > >
                            > > int callback_helper (void)
                            > > {
                            > > return callback(public _index);
                            > > }
                            > >
                            > > public_index=so me_index;
                            > > set_callback(&c allback_helper) ;
                            > >
                            > > so that a call to the callback function will result in
                            > >
                            > > callback_helper ();
                            > >
                            > > which will fetch the index you wanted, and then call the original
                            > > callback function with that value.[/color]
                            >
                            > Thanks for that, Richard.
                            > You didn't misunderstand me.
                            >
                            > I realize now, however, that I didn't mention the fact clearly that I
                            > have to register more than one callback function in the beginning
                            > (rather than set and unset them) which will then be called at any time
                            > in any order. So, I don't know when to set the public_index.[/color]

                            O-kay... so in effect, you cannot even do this:

                            public_index=in dex1;
                            function_which_ will_call_your_ callback();

                            ... more code...

                            public_index=in dex2;
                            function_which_ will_call_your_ callback();

                            and so forth, because the function will need to be called
                            asynchronously, behind your back? In that case, I'm afraid I don't know
                            a solution, either.

                            Richard

                            Comment

                            • Peter Nilsson

                              #15
                              Re: need addititional arg in given callback

                              Felix Kater wrote:[color=blue]
                              >
                              > in a given library I register callback functions with this function:
                              >
                              > bool set_callback(in t index, int (*callback_func tion)(long));
                              >
                              > I need the callback function to also pass the index which is,[/color]
                              however,[color=blue]
                              > not (re-)passed by the callback function.[/color]

                              Why do you _need_ the index?
                              [color=blue]
                              > Normally, I would just register callback functions for each
                              > index I need if the amount of callback functions was known at
                              > design time... But it isn't.
                              >
                              > Could someone help me find the right approach to solve that problem?[/color]

                              The right approach is make your callback functions independant of
                              the index, or to persuade the library writers to redesign their
                              callback interface.

                              A kludge though is something like the code below. You make your
                              callback functions take the int parameter (A, B and C below),
                              and put a wrapper around the the set_callback function...

                              #include <stdio.h>
                              #include <stdlib.h>

                              typedef int wrapper_f(long) ;
                              typedef int callback_f(int, long);

                              #define countof(x) (sizeof(x) / sizeof *(x))

                              #define blank
                              #define semicolon ;
                              #define comma ,

                              /* specify the indexes to wrap with this macro */
                              #define the_indexes(M,_ ) \
                              M( 1) _ \
                              M( 2) _ \
                              M( 7) _ \
                              M(12) _ \
                              M(42)

                              struct wt_element_t
                              {
                              const int index;
                              wrapper_f * const wrapper;
                              callback_f *callback;
                              };

                              struct wt_element_t wrapper_table[];

                              #define as_enums(I) wrapper_ ## I ## _e
                              #define as_initialisors (I) { I, wrapper_ ## I, 0 }

                              #define as_function_dec larations(I) \
                              int wrapper_ ## I (long)

                              #define as_function_def initions(I) \
                              int wrapper_ ## I (long n) \
                              { \
                              return wrapper_table[wrapper_ ## I ## _e]. \
                              callback(I, n); \
                              }

                              enum my_wrapper_enum s { the_indexes(as_ enums, comma) };
                              the_indexes(as_ function_declar ations, semicolon);

                              /* put these in a single source file */

                              the_indexes(as_ function_defini tions, blank)

                              struct wt_element_t wrapper_table[] =
                              { the_indexes(as_ initialisors, comma) };

                              int set_callback_wr apper(int index, callback_f *callback)
                              {
                              size_t i;
                              for (i = 0; i < countof(wrapper _table); i++)
                              if (wrapper_table[i].index == index)
                              {
                              wrapper_table[i].callback = callback;
                              /* install the wrapper callback function */
                              /* set_callback(in dex, wrapper_table[i].wrapper); */
                              return 1;
                              }
                              return 0;
                              }

                              /* sample usage */

                              /* your callback functions */
                              int A(int i, long n) { return printf("A(%2d, %3ld)\n", i, n); }
                              int B(int i, long n) { return printf("B(%2d, %3ld)\n", i, n); }
                              int C(int i, long n) { return printf("C(%2d, %3ld)\n", i, n); }

                              int main(void)
                              {
                              long n;

                              /* install callbacks */
                              set_callback_wr apper( 1, A);
                              set_callback_wr apper( 2, B);
                              set_callback_wr apper(12, C);
                              set_callback_wr apper(42, A);

                              /* simulate 20 pseudo random callbacks */
                              for (n = 1; n <= 20; n++)
                              {
                              size_t i = rand() % countof(wrapper _table);
                              while (wrapper_table[i].callback == 0)
                              i = (i + 1) % countof(wrapper _table);
                              wrapper_table[i].wrapper(n);
                              }

                              return 0;
                              }

                              --
                              Peter

                              Comment

                              Working...