I'm trying to share pointers between different objects so I can access data of one object from another one. I thought of creating a pointer inlet and a pointer outlet and send the pointer of the data structure out the outlet, receive it in another object through the inlet, and use the received pointer to access the data. I'm copying/modifying the simple counter external from IOhannes' pd-externals-HOWTO, but it's not working.
Here's the code I have so far: ``` #include "m_pd.h"
static t_class *share_pntr_class;
typedef struct _share_pntr { t_object x_obj; t_int i_count; t_gpointer obj_pnt; t_outlet *count_out, *addr_out; } t_share_pntr;
void share_pntr_bang(t_share_pntr *x) { t_float f=x->i_count; x->i_count++; outlet_float(x->count_out, f); }
void get_pntr_val(t_share_pntr *x) { outlet_float(x->count_out, x->obj_pnt.i_count); }
void get_pntr(t_share_pntr *x) { outlet_pointer(x->addr_out, x); }
void *share_pntr_new(t_floatarg f) { t_share_pntr *x = (t_share_pntr *)pd_new(share_pntr_class); x->i_count=f; pointerinlet_new(&x->x_obj, &x->obj_pnt); x->count_out = outlet_new(&x->x_obj, &s_float); x->addr_out = outlet_new(&x->x_obj, &s_pointer); return (void *)x; }
void share_pntr_setup(void) { share_pntr_class = class_new(gensym("share_pntr"), (t_newmethod)share_pntr_new, 0, sizeof(t_share_pntr), CLASS_DEFAULT, A_DEFFLOAT, 0); class_addbang(share_pntr_class, share_pntr_bang); class_addmethod(share_pntr_class, (t_method)get_pntr, gensym("get_pntr"), 0, 0); class_addmethod(share_pntr_class, (t_method)get_pntr_val, gensym("get_pntr_val"), 0, 0);
} ```
This is the error I'm getting: ``` src/share_mem_one.c:21:46: error: ‘t_gpointer’ {aka ‘struct _gpointer’} has no member named ‘i_count’ 21 | outlet_float(x->count_out, x->obj_pnt.i_count); ```
I understand why I get this error, but I can't see how I could share data between objects. Perhaps there's some other way to do that?
t_gpointer can only hold "gpointers", not arbitrary C pointers!
If you want to access object A in object B, you need to bind object A to some symbol and object B can then use pd_findbyclass() to get a pointer to the object. (Just make sure that you never *store* any direct pointers because they might become stale; instead, only store the symbold and use pd_findbyclass() to get the pointer.)
For a simple example, check out the source code of Pd's delay objects. [delwrite~] is bound to a symbol (given by the user), so that it can be accessed by [delread~] or [delread4~].
Note that all objects should live in a single binary, see also https://lists.puredata.info/pipermail/pd-dev/2021-01/022639.html.
Cheers,
Christof
On 23.07.2024 13:09, Alexandros Drymonitis wrote:
I'm trying to share pointers between different objects so I can access data of one object from another one. I thought of creating a pointer inlet and a pointer outlet and send the pointer of the data structure out the outlet, receive it in another object through the inlet, and use the received pointer to access the data. I'm copying/modifying the simple counter external from IOhannes' pd-externals-HOWTO, but it's not working.
Here's the code I have so far:
#include "m_pd.h" static t_class *share_pntr_class; typedef struct _share_pntr { t_object x_obj; t_int i_count; t_gpointer obj_pnt; t_outlet *count_out, *addr_out; } t_share_pntr; void share_pntr_bang(t_share_pntr *x) { t_float f=x->i_count; x->i_count++; outlet_float(x->count_out, f); } void get_pntr_val(t_share_pntr *x) { outlet_float(x->count_out, x->obj_pnt.i_count); } void get_pntr(t_share_pntr *x) { outlet_pointer(x->addr_out, x); } void *share_pntr_new(t_floatarg f) { t_share_pntr *x = (t_share_pntr *)pd_new(share_pntr_class); x->i_count=f; pointerinlet_new(&x->x_obj, &x->obj_pnt); x->count_out = outlet_new(&x->x_obj, &s_float); x->addr_out = outlet_new(&x->x_obj, &s_pointer); return (void *)x; } void share_pntr_setup(void) { share_pntr_class = class_new(gensym("share_pntr"), (t_newmethod)share_pntr_new, 0, sizeof(t_share_pntr), CLASS_DEFAULT, A_DEFFLOAT, 0); class_addbang(share_pntr_class, share_pntr_bang); class_addmethod(share_pntr_class, (t_method)get_pntr, gensym("get_pntr"), 0, 0); class_addmethod(share_pntr_class, (t_method)get_pntr_val, gensym("get_pntr_val"), 0, 0); }
This is the error I'm getting:
src/share_mem_one.c:21:46: error: ‘t_gpointer’ {aka ‘struct _gpointer’} has no member named ‘i_count’ 21 | outlet_float(x->count_out, x->obj_pnt.i_count);
I understand why I get this error, but I can't see how I could share data between objects. Perhaps there's some other way to do that?
Pd-dev mailing list Pd-dev@lists.iem.at https://lists.puredata.info/listinfo/pd-dev