QOF iteration and callbacks

Derek Atkins warlord at MIT.EDU
Thu Jun 17 10:46:33 EDT 2004

Neil Williams <linux at codehelp.co.uk> writes:

> On Thursday 17 June 2004 4:22, Derek Atkins wrote:
>> Neil Williams <linux at codehelp.co.uk> writes:
>>    qof_object_foreach(QOF_TYPE_XXX, book, my_foreach_cb, my_cb_arg);
>> Well, DUH, gnc_book_merge_foreach doesn't match the QofEntityForeachCB
>> type!  
> That's what I can't get straight. I haven't used a lot of callback routines 
> before (hazard of being self-taught) and I can't work out how to get the type 
> correct.


from qofid.h:

/** Callback type for qof_entity_foreach */
typedef void (*QofEntityForeachCB) (QofEntity *, gpointer user_data);

/** Call the callback for each entity in the collection. */
void qof_collection_foreach (QofCollection *, 
                       QofEntityForeachCB, gpointer user_data);

In other words, the QofEntityForeachCallback is a __function pointer__
with the following interface:

   void my_function (QofEntity*, gpointer);

Notice how this interface looks _JUST LIKE_ the typedef!?!?!  All you
do is pass the pointer to your implementation of this function into

>> Of course this is going to segv, you're passing completely 
>> bogus data into your function.
> I'd be grateful for an example here. I need to understand the callback and how 
> to determine the type required (I think I have that, but need a check) as 
> well as how to match that type (my real problem). 
> From this snippet:
> qof_object_foreach(GNC_ID_INVOICE, testbook,  gnc_bm_foreach, ud);
> The doxygen pages for qof_object_foreach give the types for the last two 
> parameters as types: QofEntityForeachCB and  gpointer.
> what would an empty declaration of gnc_bm_foreach need to look like in order 
> to have a compatible pointer and provide access to the object?

Well, what's QofEntityForeachCB defined as??  Look at that and
you'll get your answer...

> void gnc_bm_foreach (QofEntity obj, gpointer ud1); doesn't work. Why?
> (yes, I know calling it obj is misleading, it's an artefact of previous 
> attempts and is temporary.)

You need (QofEntity* obj, gpointer ud1).  But that's not what your
code does that you posted the other day.  Just don't cast it.  If you
DO NOT CAST and it compiles, then the interface is correct.  Casting
function pointers will always bite you down the road, because you lose
the compiler's type-checking.

> I'm presuming this is a red herring:
> void (*gnc_bm_fp) = gnc_bm_foreach;

Correct, don't do this.

> following a simple function pointer declaration prototype - (nothing to do 
> with QOF or Gnucash necessarily) although it compiles, I get the same error 
> as when I was using explicit casting - my brain is getting addled, is that 
> example a declaration or just another cast?

The QofEntityForeachCB is just a standard typedef for a function pointer.
I suggest you re-read your K&R.


       Derek Atkins, SB '93 MIT EE, SM '95 MIT Media Laboratory
       Member, MIT Student Information Processing Board  (SIPB)
       URL: http://web.mit.edu/warlord/    PP-ASEL-IA     N1NWH
       warlord at MIT.EDU                        PGP key available

More information about the gnucash-devel mailing list