libpd / libpd

Pure Data embeddable audio synthesis library
Other
1.1k stars 278 forks source link

Hook-setting functions not included in Makefile #44

Closed phrb closed 10 years ago

phrb commented 10 years ago

Hi!

I had some problems setting hooks for function calls for Pd, from libpd C API, and the problem was the z_hook_util.h not being included in the PD_FILES tag, in the Makefile.

This gave me access to the libpdset(hook) functions, and solved the hook problem I had. Thought I should let you guys know.

danomatika commented 10 years ago

The include is left out on purpose so you don't need to include the hook mechanism unless you need to aka you don't even need those source files. The same for the stuff in the util folder.

As you noted, a user who wants to use those manually includes the headers as you have done.

phrb commented 10 years ago

Ok, thanks for the answer!

I just thought it to be worth the note, since the C example provided in the code compiles, but has no output unless you include the utils.

danomatika commented 10 years ago

I've been thinking about this during the day and in revisiting it, I think what makes the most sense is to have configure-like options in the Makefile to enable compilation of the utils into the libpd build. Say something like:

make all --with-hooks --with-queues

Also, what do you mean no output? The C test should only print some stuff. It doesn't use an audio output.

phrb commented 10 years ago

I meant the prints. If you compile libpd and the example with the instructions provided (I used debian wheezy), the resulting program does not set the hooks, neither by direct assignment (dunno why) or function calls (that'll be the lack of the header).

The program then reproduces no Pd messages or prints on the terminal, for the hooks it calls are not set.

danomatika commented 10 years ago

Hrm. It should work fine. The z_hook layer in util is only needed by the Csharp wrapper since it cant set the C function pointers directly and needs those wrapper functions.

The basic C test should work fine as it is ...

phrb commented 10 years ago

Additionally, if I add the utils to the makefile, then my C code can receive messages, prints, bangs, floats and all that from a Pd patch, provided I define the functions I want, set the hooks, and tell the patch I want the data, sending a bang to it.

danomatika commented 10 years ago

Again, you should not need the utils for the lib to work. I have to see the code you're using in order to determine what's going on.

danomatika commented 10 years ago

Ok. I just cleaned and rebuilt libpd on OSX and running sampels/c_samples/c/pdtest gave me:

$ ./pdtest test.pd ./
print: 0
noteon: 0 0 0
print: 1
noteon: 0 1 0
print: 2
noteon: 0 2 0
print: 3
noteon: 0 3 0
print: 4
noteon: 0 4 0
print: 5
noteon: 0 5 0
print: 6
noteon: 0 6 0
print: 7
noteon: 0 7 0
print: 8
noteon: 0 8 0
print: 9
noteon: 0 9 0
print: 10
noteon: 0 10 0
print: 11
noteon: 0 11 0
print: 12
noteon: 0 12 0
print: 13
noteon: 0 13 0
print: 14
noteon: 0 14 0
print: 15
noteon: 0 15 0
print: 16
noteon: 0 16 0
print: 17
noteon: 0 17 0
print: 18
noteon: 0 18 0
print: 19
noteon: 0 19 0
phrb commented 10 years ago

The folder below contains my modified version of the C test, and a matching Pd patch: https://github.com/phrb/libpd_tutorials/tree/master/examples/send_receive

The only thing I did was adding z_hook_util.c to the Makefile, as seem here: https://github.com/phrb/libpd_tutorials

phrb commented 10 years ago

Could this be related to gcc, and some flag I should set/change for the makefile to work for linux?

danomatika commented 10 years ago

You shouldn't include a .c file. If it's included in the compilation, the compiler will find it's contents.

Something must be acting weird on your end because none of the changes you had to make should be necessary.

phrb commented 10 years ago

After cleaning and rebuilding libpd (Debian Wheezy) I got this:

total 20K
drwxr-xr-x 2 pbruel pbruel 4.0K Sep 20 22:16 ./
drwxr-xr-x 3 pbruel pbruel 4.0K Aug 15 23:41 ../
-rw-r--r-- 1 pbruel pbruel  302 Aug 20 19:16 Makefile
-rw-rw-rw- 1 pbruel pbruel 1.1K Sep 20 22:13 pdtest.c
-rw-r--r-- 1 pbruel pbruel  365 Aug 15 23:41 test.pd
$ make pdtest clean
cc -I../../../pure-data/src -I../../../libpd_wrapper -O3   -c -o pdtest.o pdtest.c
gcc -o pdtest pdtest.o ../../../libs/libpd.so
rm -f *.o
$ ./pdtest test.pd .
$ 
danomatika commented 10 years ago

I dunno. It should really be working. Maybe @nettoyeurny with his superior C skills might know the reason ...

phrb commented 10 years ago

When I run the code I wrote, with libpd compiled with the "modified" Makefile, I get this:

$ make pdtest clean
cc -I../../../pure-data/src -I../../libpd_wrapper -O3   -c -o pdtest.o pdtest.c
gcc -o pdtest pdtest.o ../../libs/libpd.so ../../libs/libpd.so
rm -f *.o
$ ./pdtest print_test.pd .
banged=bang_test
Received message from patch: 
Source=message_test
Symbol=test
Number of Arguments=4
Val=222.000000
$ 
phrb commented 10 years ago

Ok, thanks for your attention!

umlaeute commented 10 years ago

i can confirm that hooks do not work on linux at all.

this becomes quite obvious when printing the address of the hook-variables (e.g. &libpd_printhook) both in pdtest.c:main() (that's in the main program) and in z_libpd.c:libpd_init() (in the library):

pdtest.c:main         libpd_printhook  @ 0x8049c98
z_libpd.c:libpd_init  libpd_printhook  @ 0xb778b8ac

so the same variable name really references to different places in memory. writing anything to the the variable in the main program will not modify anything in the library, thus rendering the hooks useless.

so what is the point of omitting the z_hook-layer on purpose? the code-overhead (in terms of binary size) is minimal, the speed overhead should be virtually non-existent unless you are changing the hooks at high frequency (which i cannot find a usecase for)

danomatika commented 10 years ago

I didn't design the libpd C core. @nettoyeurny, any thoughts?

If you check the code, all the hook layer does is to wrap the setting of the function pointers:

void libpd_set_printhook(const t_libpd_printhook hook){
        libpd_printhook = hook;
}

Conceptually, I'm not sure how that's really different from doing this in your project (which the test is doing):

libpd_printhook = my_print_function;

What's interesting is why would it suddenly work when compiling in z_hook_util if you're not changing how the function pointers are being set to use the hook layer?

Aka, changing

libpd_printhook = my_print_function;

to

libpd_set_printhook(my_print_function);

Don't get me wrong, I'm not disagreeing with you in that there's an issue. I'm just wondering why compiling in z_hook_util makes it work when it shouldn't need it and apparently doesn't actually change what's going on ...

umlaeute commented 10 years ago

but that's exactly the point: the two things are conceptually different as the context differs. if (for whatever reasons and compile flags) the libpd_printhook variable really points to 2 different memory places, depending on whether it is accessed from within the library or from a calling application, that the solution is obviously to access this variable only from the correct context.

the simple way to do so, is by wrapping access to it into functions that live in the correct context. (and of course it's always good style to make (global) variables only accessible via setter/getter functions)

danomatika commented 10 years ago

Can you confirm that adding z_hook_util to the makefile and changing the hook setting to the z_hook_util functions in pdtest.c works for you on Linux? If so, then, as you say, that's probably the best option in moving forward.

I haven't run into this since I mainly use libpd with either the cpp or obj-c layers and compile in all of the libpd sources into my projects.

umlaeute commented 10 years ago

ok; i did a check using the z_hook_util functions (noticing that some are missing, e.g. the noteon hook), and indeed it is working.

i'd suggest using accessor functions everywhere rather than setting global variables directly.

danomatika commented 10 years ago

Yep. I'm working on a branch which brings the z_hook_util into the z_libpd and solves the multiple callback pointer issue.

danomatika commented 10 years ago

I've wrapped the hook function pointers with setter functions in the set-hooks branch: https://github.com/libpd/libpd/tree/set-hooks

Can y'all try it on Linux? I updated the makefile, so the pdtest c sample should work.

umlaeute commented 10 years ago

tested and works great.

danomatika commented 10 years ago

Ok, great. It was an easy fix then.