object_method in 32bit / 64bit build architecture

    Mar 24 2013 | 3:17 pm
    For a while I was compiling externals for 32bit architecture, because I used 32bit libraries. Since I can go 64bit now, I tried to compile one of the externals for 64bit architecture. The build fails with the error message that there are no symbols for object_message_imp in the x86_64 arch.
    I checked the header "ext_obex.h", something changed in SDK 6.1.1. obviously (I use the new SDK), but I don't get what's wrong with "object_method". Somebody has a hint or explanation?
    I'm using object_method to invalidate a buffer after modifying it:
    void cstesting_normalize(t_cstesting *x)
        t_buffer_obj *b = buffer_ref_getobject(x->l_buffer_reference);
        double      temp;
        double      scale;
        long          n;
        float         *tab;
        tab = buffer_locksamples(b);
    	if (!tab)
    		goto zero;
        // normalize buffer.
        n = buffer_getframecount(b);
        temp = 0;
        // find peak
        while (n--) {
            if (tab[n] >= temp) {
                temp = tab[n];
        scale = 1/temp;
        // normalize
        while (n--) {
            tab[n] = tab[n]*scale;
        object_post((t_object *)x, "normalization factor: %f", scale);
        // update waveform
        object_method((t_object*)b, gensym("dirty"));

    • Mar 25 2013 | 9:20 am
      On 64-bit architecture object_method() should be generally replaced with the object_method_direct() macro.
      From the SDK docs: "Problem: long integers as A_CANT method arguments called only through object_method()
      Solution: either redefine your A_CANT method's arguments to t_atom_long, or define your type as A_DIRECT, and make use of the object_method_direct() macro, passing in a function prototype to the macro (also see under floating point how this is required for anything which previously was A_CANT with floating point values). Technically many of these will still work properly due to the nature of how integers are passed on the stack under x64, without any change, it is still best practice."
      Let me know if this solves your issue...
      - Luigi
    • Mar 25 2013 | 6:16 pm
      You shouldn't need to use object_method_direct for this case. Only really cases which call functions prototyped with non pointer sized integers or floating point numbers as arguments or return values need to use object_method_direct.
      The change in 6.1 is that we dynamically resolve symbols in the Application process rather than via MaxAPI.framework. So you probably have not updated your projects accordingly. If you base your projects configuration off of c74support/max-includes/max-common.xcconfig, you should be fine. Specifically, the line for the linker flags, which tells the linker to resolve in this fashion.
      C74_SYM_LINKER_FLAGS = -Wl,-U,_addbang,-U,_addfloat, ...
    • Mar 25 2013 | 7:12 pm
      Ah ok, good to know... thanks Joshua.
      - Luigi
    • Apr 03 2013 | 12:28 pm
      Hey Luigi and Joshua! Thank you very much for your replies. Unfortunately I failed on the way of getting the XCode Project configured to meet all changes to 6.1. (the Linker Flags I had adopted already before), in other words, it got worse. I will report back in this thread on behalf of this problem once i fixed it.
      Since I encountered a strange behavior of the buffer~ object in 6.1 I have to stick with the former version of the framework for further development. But maybe you can tell me whether it is connected to wrong configuration or not: Reading a simple file into a buffer (no externals in the patch yet) doesn't update the display of the waveform object as expected, sometimes it looks like 0dB noise beeing read, sometimes it stays empty and sometimes it just works as expected. The same patch is working in Max 6.0.7. I attached the test-patch for this problem.
      And here the same, with sample files included: http://www.synack.ch/files/test-withSamples.zip
      Best regards, Cedric