C++ vtable and t_object ?

Mar 9, 2013 at 4:07pm

C++ vtable and t_object ?

Hi,

If my object inherits from a class that contains virtual functions and that i construct it with the operator new such in the code bellow : it crashes Max/MSP.

1. Is it something related to the vtable ?
2. Is there a workaround ?

typedef struct _mike : myObject {
    t_object ob;
    _mike( ) { }
} t_mike;

if ((x = (t_mike *)object_alloc(mike_class))) {
//
try {
    new(x)t_mike( );
} 

catch (...) {
    x = NULL;
}
//
}
#66983
Mar 9, 2013 at 4:26pm

Oops.

class ZZZ {
public:
    int a;
};

typedef struct _mike : ZZZ {
    t_object ob;
    _mike( ) { }
} t_mike;

It crashes also ; so i guess it is related to the size of the structure allocated with my “class_new / object_alloc” methods. Sorry for the soliloquy.

#241094
Mar 9, 2013 at 6:48pm

Hi again,

So i have read old threads and had a look on Graham Wakefield’s templates. I understand that it is not possible to get multiple inheritance and virtual function because of vtable issue, but one question remains.

In the scenario bellow is there any way to instantiate properly the object and be able to access later the “toto” t_symbol ?

I mean the object_alloc function seems to initialize the object in front of the memory allocated and so over the “toto” place. Thus Max/MSP do not crash until the “toto” value is used, but it does as soon it is, as the t_object is corrupted. Am i wrong ?

Anyway ?

struct ZZZ {
    t_symbol *toto;
};

typedef struct _mike : ZZZ {
    t_object ob;
    _mike( ) { }
} t_mike;

...

c = class_new("mike", mike_new, mike_free, sizeof(t_mike), 0L, A_GIMME, 0);

...

if ((x = (t_mike *)object_alloc(mike_class))) {
    new(x)t_mike( );
}
#241095
Mar 9, 2013 at 9:42pm

I believe your issue is that your topmost parent class must have t_object as the first item in your struct’s memory. Otherwise, Max will crash (it needs that in the struct header). In the above your memory layout will have t_symbol *toto first in the struct before t_object ob. So AFAICT, you will want the opposite inheritance scheme–i.e. I think you could make a ZZZ object which inherits from t_mike, but not the other way around.

If you want to add methods from some non t_object class, you’ll want to use a class composition rather than a class inheritance model. More typing, but maybe this is a solution for you.

Personally, I would simply make a simple c struct wrapper like the following and keep your C++ and Max object models separated. That’s what we usually do when integrating C++ in a Max object here.



struct ZZZ {
    t_symbol *toto;
};

typedef struct _mike : ZZZ {
    _mike( ) { }
} t_mike;

typedef  struct _wrappermike {
     t_object ob;
     t_mike *wrappedthis;
} t_wrappermike;

...

// main
wrappermike_class = class_new("mike", wrappermike_new, wrappermike_free, sizeof(t_mywrappermike), 0L, A_GIMME, 0);

...
// wrappedmike_new
if ((x = (t_wrappermike *)object_alloc(wrappermike_class))) {
    x->wrappedmike = new t_mike( );
}

...

// wrappedmike_free
if (x->wrappedmike)
     delete x->wrappedmike;
#241096
Mar 10, 2013 at 7:07am

Hi,

Thanks for reply. It is a reasonable advice ; and i guess i’ll do like that.

But in another way i would like to know if it could be possible without composing. It seems not.

AFAIK multiple inheritance do not guarantee memory layout order. So in my scenario there’s no way to have a t_object in front of the topmost structure (because i’m not allowed to change the ZZZ inheritance).

But if i’m right i don’t understand how Graham Wakefield does. Is it just because his base class contains only a static pointer and so the structure is set to zero in the memory layout (empty base class optimization) and consequently the t_object never corrupted ?

I should investigate more ;-)

class MaxCppBase {
public:
	static t_class * m_class;
...
}
#241097
Mar 10, 2013 at 7:38am

Hi,

For the futur readers :

Yep, that’s it. The Graham Wakefield’s base class is “a purely static base class for Max and MSP objects”. With EBCO the MaxCppBase should be zero ; and so everything is good (t_object is at front and sizeof(T) is right) for the “object_alloc / class_new” call with a MaxCpp5 class.

Sorry for the noise ;-)

#241098
Mar 10, 2013 at 9:31am

Yes. All is fine if topmost class begins with t_object. Any other scenario will not work with the max object model.

#241099

You must be logged in to reply to this topic.