Linking attributes to a struct within an object

    Aug 31 2013 | 5:30 am
    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 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?)

    • Aug 31 2013 | 6:41 am
      thanks! i'll look into these
    • Aug 31 2013 | 2:48 pm
      Hi, You can have a look at for OBJECT_ATTR.
    • Aug 31 2013 | 4:40 pm
      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 !
    • Aug 31 2013 | 8: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).
    • Sep 01 2013 | 10: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....?
    • Sep 03 2013 | 6:39 am
      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...
      - Luigi
    • Nov 12 2013 | 11: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;
      // 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?
    • Nov 12 2013 | 4:29 pm
      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.
    • Nov 12 2013 | 4:38 pm
      Actually it looks to work even with the warning. Thank you a lot!