On 5/12/2011 13:44, pozz wrote:
> Il 12/05/2011 05:10, Shao Miller ha scritto:
>> In your example code, you are using the same call-back for every
>> different number. If you are going to be using the same call-back, is
>> there a reason why you cannot pass a 'void *' context that points
>> directly to an element of an array of 'int'? As in:
>
> Oh yes, it is exactly what I wrote in the previous post. The approach is
> good, but two small drawbacks I posted.
>
So if you are using the same call-back function no matter which element
is being used, would it make sense to remove the redundant '.fn' member
and simply pass a context which points directly to an element of an
array of 'int'?
>
>> But... That's what malloc() and the
>> other memory allocation functions are for...
>>
>> void blah(void) {
>> int *i;
>>
>> i = malloc(sizeof *i);
>> if (!i) {
>> /* Note an error */
>> return;
>> }
>>
>> *i = 5;
>> SomeApiRegisterCallback(my_callback, i);
>> return;
>> }
>>
>> Remember to free() the pointer once you've finished with it. 
>
> malloc() and free() are not present in my embedded system. I have to use
> only static allocation.
That detail seems like a good idea to share when discussing your
scenario.
Can your function which registers the call-back wait for the call-back
to be completed?
If not, is the call-back one which will be called repeatedly, but should
always use the same context?
Do you have thread synchronization functions available to you?
Could you have a dedicated thread whose sole purpose is to provide for
non-static storage? Such a thread could "abuse" recursion in order to
"allocate" more memory in the form of automatic objects. The memory
could run out, obviously, but could save you from having a large array
with static duration and having every possible number in it. Or is
having such a large array not an issue?
Or could you have a thread to "wrap" each context? A thread for "3", a
thread for "5", etc.? That'd seem _quite_ wasteful, but maybe that's an
option!
In my opinion, if you are targeting a particular environment (which
doesn't have malloc() and free() ), then perhaps you needn't be overly
concerned about portability! If the environment is documented as
allowing for an 'int' to be cast to 'void *' and back again, then that's
that. (But maybe avoid expecting such code to be portable, in a
standard sense.)
Have a pleasant day.