Closed phrb closed 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.
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.
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.
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.
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 ...
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.
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.
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
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
Could this be related to gcc, and some flag I should set/change for the makefile to work for linux?
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.
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 .
$
I dunno. It should really be working. Maybe @nettoyeurny with his superior C skills might know the reason ...
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
$
Ok, thanks for your attention!
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)
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 ...
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)
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.
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.
Yep. I'm working on a branch which brings the z_hook_util into the z_libpd and solves the multiple callback pointer issue.
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.
tested and works great.
Ok, great. It was an easy fix then.
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.