Forums > Dev

testobex example in pattrsdk.pdf

Jul 11 2006 | 9:47 pm

I tried compiling the testobex external in the pattrsdk.pdf and found a few errors. I corrected the errors but still the example does not work correctly.

firstly, void *class_testobex was declared but then was used as testobex_class twice. so i changed it to class_testobex.

secondly, the attribute ‘operand’ was registered but then ‘data’ was used in place of ‘operand’ . I changed all instances of ‘data’ to ‘operand’ and it compiled fine.

When i set up a test in max however, the output value was always 0. I did put a value for operand in the object ‘command line’ ie
@operand 34

any idea on how to correct this?


Jul 12 2006 | 7:09 pm

I decided to post the source. It is the same as in pattrsdk.pdf with the changes i mentioned.

I have it working when i manually set operand to the value (which i commented out here), so maybe i am confused by the point of
//handle attribute arguments (e.g. @operand 0.5)
attr_args_process(x, ac, av);

does it not set the values of the attributes to the variable you create and register with class_addattr(c, attr); ?


#include "ext.h"
#include "ext_obex.h"
typedef struct _testobex
{ t_object ob;
void *obex;
float operand;
void *out;
} t_testobex;

void *class_testobex;
void *testobex_new(t_symbol *s, long ac, t_atom *av);
void testobex_free(t_testobex *x);
void testobex_int(t_testobex *x, long d);
void testobex_float(t_testobex *x, double f);

void main(void)
{ t_class *c;
t_object *attr;
long attrflags = 0;

// define the class – A_GIMME required for attributes
c = class_new("testobex", (method)testobex_new, (method)testobex_free, sizeof(t_testobex), (method)0L, A_GIMME, 0);

// register the obex object’s offset
class_obexoffset_set(c, calcoffset(t_testobex, obex));

// create and register an attribute (attr_offset)
attr = attr_offset_new("operand", _sym_float32, attrflags, (method)0L, (method)0L, calcoffset(t_testobex, operand));
class_addattr(c, attr);

// create and register some methods
class_addmethod(c, (method)testobex_int, "int", A_LONG, 0);
class_addmethod(c, (method)testobex_float, "float", A_FLOAT, 0);

// add dumpout and quickref methods
class_addmethod(c, (method)object_obex_dumpout, "dumpout", A_CANT, 0);
class_addmethod(c, (method)object_obex_quickref, "quickref", A_CANT, 0);

// register the class as an instantiable box
class_register(CLASS_BOX, c);

// set the global class variable
class_testobex = c;

void *testobex_new(t_symbol *s, long ac, t_atom *av)
{ t_testobex *x = NULL;
// allocate a new object
if (x = (t_testobex *)object_alloc(class_testobex))
{ // important: initialize class members before processing
// attribute args. otherwise, you might replace data.
x->operand = 0;

//handle attribute arguments (e.g. @operand 0.5)
attr_args_process(x, ac, av);

// if (ac > 1) x->operand = atom_getlong(av+1);

// create a dumpout outlet, used by attributes
object_obex_store(x, _sym_dumpout, outlet_new(x, NULL));
// create another outlet
x->out = outlet_new(x, NULL);
return x;

void testobex_free(t_testobex *x)
{ ; // nix

void testobex_int(t_testobex *x, long d)
{ // int in, int out
outlet_int(x->out, (long)((float)d * x->operand));

void testobex_float(t_testobex *x, double f)
// float in, float out
outlet_float(x->out, f * x->operand);

Viewing 2 posts - 1 through 2 (of 2 total)

Forums > Dev