// ! OpenSceneGraph managed smart_ptr. template < typename T > public ref class smart_ptr{ public : typedef T element_type; smart_ptr() : _ptr( 0 ) {} smart_ptr(T * ptr) : _ptr(ptr) { if (_ptr) _ptr -> ref (); } smart_ptr( const smart_ptr % rp) : _ptr(rp._ptr) { if (_ptr) _ptr -> ref (); } ~ smart_ptr() { if (_ptr) _ptr -> unref(); _ptr = 0 ; } smart_ptr % operator = ( const smart_ptr % rp) { if (_ptr == rp._ptr) return * this ; T * tmp_ptr = _ptr; _ptr = rp._ptr; if (_ptr) _ptr -> ref (); // unref second to prevent any deletion of any object which might // be referenced by the other object. i.e rp is child of the // original _ptr. if (tmp_ptr) tmp_ptr -> unref(); return * this ; } inline smart_ptr % operator = (T * ptr) { if (_ptr == ptr) return * this ; T * tmp_ptr = _ptr; _ptr = ptr; if (_ptr) _ptr -> ref (); // unref second to prevent any deletion of any object which might // be referenced by the other object. i.e rp is child of the // original _ptr. if (tmp_ptr) tmp_ptr -> unref(); return * this ; } // T% operator*() { return *_ptr; } T * operator -> () { return _ptr; } T * get () { return _ptr; } bool operator ! () { return _ptr == 0 ; } // not required bool valid() { return _ptr != 0 ; } T * release() { T * tmp = _ptr; if (_ptr) _ptr -> unref_nodelete(); _ptr = 0 ; return tmp; } private : T * _ptr;};
如此这般折腾以后,终于可以在托管类中间使用智能指针了: public ref class Scene { protected : smart_ptr < osg::GraphicsContext > gc; smart_ptr < osg::Group > root; smart_ptr < osgViewer::Viewer > viewer; smart_ptr < osg::Camera > camera;.}
跨越了智能指针的障碍以后,还有很多问题有待于解决。像osg::Vec3这些常用类只能重写以便于调用。像查找节点FindNode这种函数: ref class NodeFound { public : String ^ name; smart_ptr < osg::Node > osgNode; }; NodeFound ^ FindNode(String ^ name) { FindNodeVisitor findNodeVisitor; findNodeVisitor.name = MarshalString(name); root -> accept(findNodeVisitor); if (findNodeVisitor.node == NULL) throw gcnew Exceptions::NodeNotFoundExpection(); NodeFound ^ nodeFound = gcnew NodeFound(); nodeFound -> name = name; nodeFound -> osgNode = findNodeVisitor.node; return nodeFound; return nullptr; }
只能定义一个新的结构作为返回值,否则C#语言无法使用,因为它不能解析一个智能指针。~~~或许,还有别的方法可以用吧,比如用IntPtr这种,但可能又会脱离了智能指针的保护,变的危险起来。 继续学习中~