thanks IOhannes, that's very helpful. by changing the callback signature to:
euclid_new(t_symbol *s, int argc, t_atom *argv)
i was able to get it working with A_GIMME. but one thing still bothers me: this is the constructor for the class, and i really only want to support instantiation with a single (float) creation argument. why should i have to jump through the hoops of A_GIMME? shouldn't the following signature:
euclid_new(t_floatarg f)
registered with class_new(..., A_DEFFLOAT) be sufficient for this simple case? this worked for me on 0.43.4; why doesn't it work in 0.47?
thanks again,
_chris
On Mon, Feb 6, 2017 at 3:57 AM, IOhannes m zmoelnig zmoelnig@iem.at wrote:
On 2017-02-06 07:42, Chris Chronopoulos wrote:
Code is attached. Any suggestions? What's this typechecking/A_GIMME
Pd has special, "optimized" functions to check the types of arguments.
basically, if you have a callback function (and from a pure "C" perspective, the class-methods of an objects are callback functions), you must correctly call that function. that is: if the callback function expects a symbols and then a float ("void foo_mess(t_myobject*x, t_symbol*s, t_float f)"), you must actually call it with a symbol and then a float ("foo_mess(x, s2, 2.3)"), to ensure that the compiler will put the correct bits at the right positions.
now in Pd, an external can wish for "any" function signature of the callback it wishes for, but it is the task of Pd (core) to actually call that callback function correctly. since "any" signature is pretty broad and it is tedious to write special callback callers for all the possibilities, it offers a (slightly less convenient) generic solution for "non-standard" callbacks: pass a list of atoms (aka A_GIMME) messages with more that 5 atoms are "non-standard", and therefore you must use A_GIMME.
the function signature of an A_GIMME is: int argc, t_atom*argv you then can iterate over the <argc> atoms in the <argv> array, and use them whoever you please (mainly: check that each element is of correct type, and use atom_getfloat() resp atom_getsymbol() to acccess the values).
i suspect (without having looked at your code), that you were simply changing the type to A_GIMME when registering the callback (in the class_addmothod() function), but then didn't bother to change the function signature of the actual callback function.
so if your callback signature is: void foo_mess(t_myobject*x, t_symbol*s, t_float f); and you register it with class_addmethod(x, (t_method)foo_mess, gensym("foo"), A_GIMME, 0);
then the system will end up calling foo_mess with the following arguments:
- the first 4 bytes are the address to the object (good)
- the next 4 bytes are an int value (bad because you are expecting the 4
bytes to be the address of a symbol)
- the next 4 bytes being the address of some t_atom-array (bad, because
you are expecting it to be 4 bytes of an ieee758 floating point number) (for the sake of simplicity the above example assumes a 32bit system)
if you then happen to dereference so-acquired symbol, it will hopefully go kaboong (hopefully insofar as it will go kaboong without launching the missilies first)
mfgasdr IOhannes
Pd-list@lists.iem.at mailing list UNSUBSCRIBE and account-management -> https://lists.puredata.info/ listinfo/pd-list