Forums > Dev

Linking attributes to a struct within an object

August 30, 2013 | 10:30 pm

Hi there – I’ve been trying to add attributes to my custom external, but find the documentation rather sparse.

My object’s struct looks rather like this:

typedef struct _myObj {
t_pxobject x_obj;
otherStruct *e;
} t_myObj;

with otherStruct defined as (shortened here):
typedef struct otherStruct
{
float x,y,offsetx,offsety,angle;
} otherStruct;

I have a whole list of strings:
const char* paramNames[5] = {"x","y", "offsetx","offsety","angle"};
To set up the attributes I do the following

for (i=0;i<kNumParams;i++) {
int offset = i*sizeof(t_atom_float);
t_object *attr = attr_offset_new ( paramNames[i], _sym_float32, 0, (method)0L, (method)0L, offset);
if (attr == NULL) {
object_error((t_object *)x, "Couldn't create new attr at offset %ld",offset);
} else {
t_max_err err = object_addattr(x->e, attr);
if (err != MAX_ERR_NONE) {
object_error((t_object *)x, "object_addattr failed with error code %ld",err);
}
}
}

But this crashes in ‘object_addattr’. What am I doing wrong? Can the first argument in ‘object_addattr’ just be any old struct, or does it have to be a t_object*? (The fact it’s a void* seems to imply that it’s OK, but who knows?)


August 30, 2013 | 11:41 pm

thanks! i’ll look into these


August 31, 2013 | 7:48 am

Hi,
You can have a look at for OBJECT_ATTR.

Cheers



August 31, 2013 | 9:40 am

Yes, you are right ! It works but I don’t know where is my attribute… In fact, it seems that m_order isn’t the variable of my attribute. I used to use object_attr_get so I didn’t realize the problem. OBJ_ATTR_LONG (&m_order) isn’t the solution, I’ll have to investigate…

Thanks for this feedback !


August 31, 2013 | 1:04 pm

I tried OBJ_ATTR_FLOAT using pointers directly to my struct, but it didn’t work. I’ve given up and refactored the object so that it’s not using a struct within a struct any more. Then I can just use CLASS_ATTR_FLOAT (albeit with 30 lines more code).


September 1, 2013 | 3:14 am

I think I can confirm this. In my former version of the code (posted in the initial message), in which I used obj_addattr (which is what the OBJ_ATTR macros use) to point to an arbitrary struct (NOT an ‘object’ struct, i.e. without the t_pxobject as the first member), there seemed to be no way to directly change the value of it by simply writing to the point with which it was initialized.

When I then refactored the code so that all the arbitrary struct members became part of my Max object struct, I could change the attribute value by directly writing to that memory space.

So, in short, it seems neither CLASS_ATTR nor OBJ_ATTR macros work with any struct that doesn’t have t_pxobject as a first member….?


September 2, 2013 | 11:39 pm

Sorry, I saw this thread late, but – yes – to answer mnorris question please refer to my thread that Nicolas kindly dug out of the archives. The only thing I would like to add is that in this specific case I use the _sym_pointer qualifier as it is more correct for the type of use. Of course custom getter and setter are mandatory…

Best

- Luigi


November 12, 2013 | 3:40 am

Hi there!

I am a (very) newbie in MaxMSP and I already have to create my own external. My problem is very close to yours (I guess): I want to read 5 text files and get access to each one of them in my object. To do this I have created a struct to fill in the data. Each time a message "read" incomes I create a new structure that I fill with the data from the text file, my problem is how to get access to those 5 structures in the rest of my program?
Should I add some attributes to my object (but add then 5 struct attributes?)

the structures:
typedef struct _recognition {
t_object p_ob;
void *p_outlet;
} t_recognition;

typedef struct _model {
char id;
double A[NBSTATE][NBSTATE];
double cov[NBSTATE*NBFEAT][NBFEAT];
double mu[NBSTATE][NBFEAT];
} t_model;

In the main
c = class_new("recognition", (method)recognition_new, (method)NULL, sizeof(t_recognition), 0L, A_DEFLONG, 0);
class_addmethod(c, (method)myobject_read, "read", A_DEFSYM, 0);

the functions:

void myobject_read(t_object *x, t_symbol *s)
{
defer(x, (method)myobject_doread, s, 0, NULL);
}

void myobject_doread(t_object *x, t_symbol *s)
{
// ….. find the filename etc
myobject_openfile(x, filename, path);
}

t_model *myobject_openfile(t_object *x, char *filename, short path)
{
t_filehandle fh;
char *buffer;
t_ptr_size size;
int count=0;

t_model *mod = (t_model *)malloc(sizeof(t_model));

if (path_opensysfile(filename, path, &fh, READ_PERM)) {
object_error(x, "error opening %s", filename);
return mod;

}

mod->id=filename[6];

// allocate memory block that is the size of the file
sysfile_geteof(fh, &size);
buffer = sysmem_newptr(size);
// read in the file
sysfile_read(fh, &size, buffer);
sysfile_close(fh);

// fill the structure mod

sysmem_freeptr(buffer); // must free allocated memory

return mod;
}

So each time there is a "read" message, I create and fill a new structure t_model *mod and send back a pointer to this structure but where can I access to it? And how to be sure I create a new structure for each read and not writing over?


November 12, 2013 | 8:29 am

Thank you to answer me so quickly!
I need indeed to access my five t_model in other methods of my external. I think you are right saying I need an array of pointers. But how I can instantiate them without a malloc? I have found the function system_newptr but it looks to work only with pointers of type char and I need pointers of type t_model.
I have tried this:
in my object structure:
t_model *ptr_model[5];

in the method to instantiate the object (my object_new)
for(int i=0; iptr_model[i]=sysmem_newptr(sizeof(t_model));
}
and I get a warning "Incompatible pointer type assigning to ‘t_model *’ from ‘t_ptr’"

Is there any other function to do so?

I am sure that my problem is about knowing generic techniques for Max/MSP objects and I have already make smaller objects from my own and read the examples in MaxSDK in order to understand the basics but it looks not to be enough.


November 12, 2013 | 8:38 am

Actually it looks to work even with the warning. Thank you a lot!


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