Extern and Constructors: what to do?
Monkey Forums/Monkey Programming/Extern and Constructors: what to do?
| ||
Oof, I'm at my wits end here. Does anyone else feel we should be allowed to Extern "New"? I'm hitting walls trying to get external libraries to work with C++. Some of the libs do not allow empty constructors, so I'm wrapping Create() functions, but then I'm not able to Extend any classes. I'm dealing with wxWidgets. I am almost at a point where this may work as an out-of-the-box solution if Monkey can have this changed, but this may be a tall order to request. |
| ||
Adam, does the answer to this question give you any "new" ideas? http://stackoverflow.com/questions/11091801/extern-must-have-access-to-class-constructor |
| ||
no, but i appreciate the effort. to clarify: Extern Class wxButton ="_wxButton" Function Create:wxButton( args ) End Public cpp native code: // C++ side class _wxButton: public wxButton { public: _wxButton::_wxButton():wxButton() {}; //empty constructor, ok with Monkey _wxButton::_wxButton(args):wxButton(args) {}; //*** NO WAY TO ACCESS in Monkey _wxButton Create( args ) { return new _wxButton( args ); //*** NO proper way to cast this if extended by Monkey }; }; given the above, the way i currently implemented it, i CANNOT extend wxButton in Monkey, because the C++ code returns _wxButton, and we cannot "dynamic_cast" from a base class to a derived class. But if Monkey were to allow me to Extern "new": Extern Class wxButton ="_wxButton" Method New( args ) End Public then the C++ code would return a new instance of an extended object. i should have pushed for this a while ago, but i thought i could get around it. |
| ||
The problem is that monkey currently uses the c++ constructor to initialize fields to default values, since c++ (pre-2011) has no way to do this. This means by the time the new() method is called, the object has already been constructed as far as c++ is concerned, so it's too late for extern ctors to be called. However, I have recently been considering changing this so that fields are initialized inline inside each constructor instead, which will lead to slightly more generated code if you overload new() but should be faster. At which point extern ctors make more sense... No timeline on this though sorry. I haven't given it a whole lot of thought as yet and I'm currently working on some other stuff but I'll take a closer look at it soon. |
| ||
the time the new() method is called, the object has already been constructed ahhh, that's right, i forgot about that. No timeline on this though sorry. ok, no problem. i'll table it for now. |
| ||
Ok, if anyone else is struggling to bind Monkey to a C++ library: the way to do this is to wrap the cpp classes. I'm almost copy-pasting the constructor args from the wxWidget docs for Create(). and on the monkey side, this is where more of the work is done, but not terrible: Using the objects is a two step process: button = New wxButton, button.Create(), but you can now Extend the Extern Class properly. Although, I do still wish Monkey would relax on the Extern New a bit so I can do this: Class wxButton Extends wxControl = "_wxButton" Method New(args) = "m_new" End class _wxButton: public Object, public wxButton { public: wxButton* obj; void m_new() {}; void m_new(args) { obj = new wxButton(args); } } So... with this and if Monkey will get the #LIBS config var added to C++ target, I can get wxMonkey to work out of the box (no need for target building). nom nom nom |
| ||
scratch that, it doesn't work. if i want to pass an extended Extern object, like wxSizer.Add(button1), it won't work unless i wrap the extern method.... hrmmm. |