[PD] arguments not passed to an external

IOhannes m zmoelnig zmoelnig at iem.at
Mon May 26 16:36:32 CEST 2014

Hash: SHA256

On 2014-05-26 14:28, Alexandros Drymonitis wrote:
>> Here you go: 
>> https://github.com/alexandros301/powSine-/blob/master/powSine~.c


a few remarks:

- - you should *never ever* use the full-path when you #include a file.
it should read
 #include "m_pd.h"
and then you should add the proper INCLUDE path to your build-system,
so the compiler can actually find the file.

at least, if you ever want your external to be compilable on a machine
that is *not* running Pd-0.45-3 (vanilla) on an OSX computer.

- - you should go and make it a habit to name the C-files the same as
your objects. e.g. the code for [powSine_lookup~] should be in a file
this allows to integrate it very easily with other build-systems, e.g.
the template/Makefile [1] which is already known to be able to compile
on a plethora of systems (at least if you don't use absolute includes :-))

having said that, i compiled your external and it behaves as expected.
at least, if i post() the x_frequency and x_power values, they give
the values as specified via the object-arguments.

some thoughts, what could be the cause of your problems:

- - i don't know how you tested whether the arguments are passed to the
object. however in your code you ignore the values of x_frequency and
x_power, so it is no wonder that they do not have any effect.

- - you are using "short argc" instead of "int argc" as i suggested.
this could indeed be the problem, as C is a very low-level language.
this means, that when the constructor-function "powSine_lookup_new" is
called, it is really only called with the arguments aligned in memory
as Pd expects them, not like you would like to have them.
e.g. really the function callback for the constructor will have
arguments like (in raw bytes):
  0x09 0xd0 0x2e 0xb0 0x00 0x00 0x00 0x02 ...
now you are interpreting these bytes according to your
function-definition as "t_symbol*" (a pointer, taking e.g. 4 bytes),
"int" (a number taking 4 bytes) and so on.
which means that you end up with your arguments having the values:
  int argc  =0x00000002; /* this really is "2" */
(i'm assuming 4 bytes for the t_symbol* pointer, which is only true on
32bit systems; but it saves me some typing with no added info)
now the problem is, that if you assume that argc is of type "short",
then you are really only reading the first 2 bytes (after the
t_symbol*), resulting in:
  int argc =0x0000; /* oops, this is "0" */

you are quite lucky, that argc is indeed 0, as of course the arguments
following the "argc" bytes, will now have a weird offset, so what you
think is your argv is indeed just garbage.

now the actual order (and alignment) of arguments depends on a number
of things, including your operating system.
but it still holds true, that you cannot just exchange an int16 (aka
"short") for an int32 (aka "int"), in a callback function without
calling for desaster. (no matter if this is what eric's book says).
even more so, if you do a typecast when registering the callback
function (remember that you do cast "powSine_lookup_setup" to
"(t_newmethod)") which will circumvent a whole bunch of type-checking
the compiler could have done for you.

anyhow, a good start to debug such problems, is to check whether the
values you deal with are really the values you expect.
e.g. what is the value of "argc", depending on how many arguments you
pass to the object.
for starters use "post()" to print the values.
then you can learn how to use a debugger, and inspect the context of
your running program.


Version: GnuPG v1
Comment: Using GnuPG with Icedove - http://www.enigmail.net/


More information about the Pd-list mailing list