Extern and Constructors: what to do?

Monkey Forums/Monkey Programming/Extern and Constructors: what to do?

AdamRedwoods(Posted 2013) [#1]
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.


AndroidAndy(Posted 2013) [#2]
Adam, does the answer to this question give you any "new" ideas?

http://stackoverflow.com/questions/11091801/extern-must-have-access-to-class-constructor


AdamRedwoods(Posted 2013) [#3]
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.


marksibly(Posted 2013) [#4]
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.


AdamRedwoods(Posted 2013) [#5]
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.


AdamRedwoods(Posted 2013) [#6]
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


AdamRedwoods(Posted 2013) [#7]
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.