About Monkey 2 › Forums › Monkey 2 Programming Help › extending a C++ class with GC ?
This topic contains 7 replies, has 3 voices, and was last updated by
codifies
2 years, 5 months ago.
-
AuthorPosts
-
November 18, 2016 at 3:22 pm #5205
I’m trying to extend a C++ class (without modifying it) so it can be GC’d like a “normal” MX2 object…
Monkey1234567891011// rectangle.h// class to wrap the idea is not to modify thisclass Rectangle {public:float width,height;Rectangle();Rectangle(float w, float h);float area();~Rectangle();};Monkey123456789101112131415161718// rectangle.cpp// class to wrap the idea is not to modify this#include <cstdio>#include "Rectangle.h"Rectangle::Rectangle(float w, float h) {width=w;height=h;printf("created %f %f\n",w,h);}float Rectangle::area() {return width * height;}Rectangle::~Rectangle() {printf("Rectangle Destroyed\n");}Now to be honest C++ has to be my least favourite language, and thus not something I’m particularly strong in, so its entirely possible I’m doing something wrong…
I’m wrapping the Rectangle class into RectangleMX
Monkey12345678910111213// wrap.h#include "Rectangle.h"#include <bbmonkey.h>class RectangleMX : public bbObject, public Rectangle {public:RectangleMX(float w, float h);~RectangleMX();};RectangleMX* createRectangle(float w, float h);float getRectangleArea(RectangleMX* r);Monkey123456789101112131415161718192021222324// wrap.cpp#include "wrap.h"#include <bbmonkey.h>#include <cstdio>Rectangle::Rectangle() { } // ??RectangleMX::RectangleMX(float w, float h) {Rectangle(w,h); // disambiguation?}RectangleMX::~RectangleMX() {printf("rectMX destroyed");}RectangleMX* createRectangle(float w, float h) {RectangleMX* r = new RectangleMX(w, h);return r;}float getRectangleArea(RectangleMX* r) {return r->area();}and (finally) how I’m “testing” it…
Monkey123456789101112131415161718192021222324252627// testRectangle.monkey2#import "wrap.h"#import "Rectangle.cpp"#import "wrap.cpp"Externstruct Rect="RectangleMX"field width:float, height:FloatEndfunction createRectangle:Rect ptr(w:float, h:float)function getRectangleArea:Float(r:Rect ptr)Publicfunction Main()for local i:int = 1 to 20useRect(2,i/2.0)NextEndfunction useRect(w:float, h:float)local r:Rect Ptrr = createRectangle(w,h)print "area "+getRectangleArea(r)EndCurrently I’m stumped as it seems to be getting GC’d immediately on creating, and I’d have thought that the rectangleMX destructor would have been called to – but then that shows you what I know about c++
Attachments:
November 18, 2016 at 7:17 pm #5212Close!
The problem is with the ‘disambiguation’ bit in RectangleMX’s ctor – your code actually creates a temporary Rectangle on the stack that is immediately destroy when RectangleMX’s ctor exits.
To call a super class ctor from a ctor you need to use this special syntax:
Monkey123RectangleMX::RectangleMX(float w, float h):Rectangle( w,h ) {}November 18, 2016 at 7:32 pm #5215cool, thanks mark
(just why I dislike c++
)
while it works, the Rectangle destructor is never called ?
I’ve tried assigning multiple instances to the same local in a function called 1000’s of times while calling GCCollect() in the loop calling the function assigning the classes….
November 18, 2016 at 7:52 pm #5216Try this to create the rectangle:
Monkey12RectangleMX* r = bbGCNew<RectangleMX>( w,h );This is mx2’s special ‘new’ to create GC aware objects – it must be used with classes that extend bbObject.
This makes this approach unsuitable for libraries that use ‘factory’ methods to produce objects, but it should work for bullet?
November 18, 2016 at 8:07 pm #5217ding ding ding, we have a winner, thanks Mark
I wasn’t actually thinking of bullet (as anyhow you promised it soon ;-p – still tempted to throw a very limited temporary thing together mind…)
Very good point about factory methods but you could always call the factory place the pointer in a field of a GC’d class that you *then* return from the wrapper… :-/ !
I’m thinking about putting together a blog post about wrapping for MX2 and including this idea as well, you wouldn’t happen to have any other wrapping secret sauce, that you think would be good to go in such a blog post would you?
November 18, 2016 at 8:29 pm #5219but you could always call the factory place the pointer in a field of a GC’d class that you *then* return from the wrapper… :-/ !
Yes, and this is what I thought you were thinking of in the first place re: bullet. But I like this abuse of multiple inheritance much more (in fact, the litehtml modules uses this approach) – separate wrapper objects get messy as you need to foward ALL methods and allowing users to override virtual methods is tricky.
November 18, 2016 at 10:47 pm #5224Could you post the entire rectangle example codes? I have difficulties with the gcnew in cpp side and how it becomes a simple new in mx2. (Or you can’t ‘new’ it in mx2?)
ThxNovember 18, 2016 at 10:48 pm #5225I’m tidying the code and just writing it all up now, I’ll post the link before long…
-
AuthorPosts
You must be logged in to reply to this topic.