Notes For Contributors

wx.NET sources fall into two parts: The C# implementation of the wrapper and the implementation of the wx-c.dll.

Allthough C# provides a very convenient way to call native implementations compiled into a DLL, the matching of the different object models and memory managements still provides several difficulties. Refer to the documentation of wx.Object on this issue.

Also please note some guide lines that the current code base unfortunately ignores sometimes.

One example for the rules: Return a string mapped to a string in a C++ container (only an example).
 class wxStringMap 
 {
   public:
   wxStringMap();
   virtual ~wxStringMap();
   bool HasValueFor(const wxString& key) const;
   const wxString& ValueFor(const wxString& key) const;
 };
The following wrapper ignores the rules as presented above whereever possible. The implementations in wx-c.dll.
 extern "C" __declspec(dllexport) wxStringMap* wxStringMap_CTor()
 {
    return new wxStringMap();
 }
 extern "C" __declspec(dllexport) void wxStringMap_DTor(wxStringMap* self)
 {
    delete self;
 }
 extern "C" __declspec(dllexport) bool wxStringMap_HasValueFor(wxStringMap* self, const char* key)
 {
    return self->HasValueFor(key);
 }
 extern "C" __declspec(dllexport) const wxString* ValueFor(wxStringMap* self, const char* key)
 {
    return &(self->ValueFor(key));
 }
The implementation in wx.NET.dll.
 namespace wx
 {
   class StringMap : Object
   {
        [DllImport("wx-c")] static extern IntPtr wxStringMap_CTor();
        public StringMap() : base(wxStringMap_CTor()) {}
        // but where is the cosntructor for IntPtr
 
        [DllImport("wx-c")] static extern void wxStringMap_DTor(IntPtr self)
                protected virtual void Dispose(bool disposing)
                {
            bool still_there = RemoveObject(wxObject);
                        if (!disposed)
                        {
                lock (Object.DllSync)
                {
                                        if (wxObject != IntPtr.Zero && memOwn && still_there)
                                        {
                                                wxStringMap_DTor(wxObject);
                                        }
                                }
                                
                                virtual_Dispose = null;
                                wxObject = IntPtr.Zero;
                                memOwn = false;
                --validInstancesCount;
            }

                        disposed = true;
        }
        // this is a lot of copy/paste stuff that is not necessary since C++
        // provides a virtual destructor.
 
        [DllImport("wx-c")] static extern bool wxStringMap_HasValueFor(IntPtr self, string key)
        public bool HasValueFor(string key)
        {
            return wxStringMap_HasValueFor(wxObject, key);
        }
        // no unicode support since standard marshalling for strings is: BSTR
        // bool will only work iff the C++ compiler uses full word width (4 bytes on 32 bit architectures) for bool.
 
        [DllImport("wx-c")] static extern IntPtr wxStringMap_ValueFor(IntPtr self, string key)
        public string ValueFor(string key)
        {
            return (wxString) Object.FindObject(wxStringMap_ValueFor(wxObject, key), typeof(wxString));
        }
        // correct but useless cal to wx.Object.FindObject(). This method is appropriate to reuse
        // previously generated wrappers. But strings will be newly generated when requested.
        // no unicode support.
   }
 }

The wrapper will look something like the following when observing the guiding rules. Make up your mind on the effect!

 #include "local_events.h"
 #include "wxnet_globals.h"
 
 class _StringMap : public wxStringMap
 {
    DECLARE_DISPOSABLE(_StringMap)
    public _StringMap() : wxStringMap(), m_onDispose(NULL) {}
 };
 
 WXNET_EXPORT(wxStringMap*) wxStringMap_CTor()
 {
    return new _StringMap();
 }
 
 // we do not need a method for destruction since the wrapped class supports virtual destruction.
 
 WXNET_EXPORT(void) wxStringMap_RegisterDispose(_StringMap* self, Virtual_Dispose onDispose)
 {
    if (self) self->RegisterDispose(onDispose);
 }
 
 WXNET_EXPORT(char) wxStringMap_HasValueFor(wxStringMap* self, const wxString* key)
 {
    if (self && key)
        return self->HasValueFor(*key);
    else
        return 0;
 }
 // this avoids access violations on NULL pointers and uses C standard type char instead of bool
 // unicode will be supported if wxWidgets has been compiled for unicode support
 
 WXNET_EXPORT(wxString*) ValueFor(wxStringMap* self, const wxString* key)
 {
    if (self && key)
       return new wxString(self->ValueFor(*key));
    else
        return NULL;
 }
 // unicode support and return of fresh strings only.
And now the correlated C# implementation.
 namespace wx
 {
   class StringMap : Object
   {
        #region CTor
        [DllImport("wx-c")] static extern IntPtr wxStringMap_CTor();
        [DllImport("wx-c")] static extern void wxStringMap_RegisterDispose(IntPtr self, Virtual_Dispose onDispose);
        static IntPtr LockedCTor()
        { // memory allocation at least on Windows is not thread safe.
          // so, we have to synchronize all C++-code allocating and deallocating
          // memory from 
            lock (wx.Object.DllSync)
            {
                return wxStringMap_CTor();
            }
        }
        public StringMap() : this(LockedCTor())
        {
            // the wrapper shall be deactivated on deleting the C++ instance
            this.virtual_Dispose = new Virtual_Dispose(VirtualDispose);
            this.memOwn = true;
            wxStringMap_RegisterDispose(this.wxObject, virtual_Dispose);
        }
        public StringMap(IntPtr wxObject) : base(wxObject) {}
        #endregion
 
        #region Public Methods
        [DllImport("wx-c")]
        [return: MarshalAs(UnmanagedType.U1)] // redefines marshalling of result type bool
        static extern bool wxStringMap_HasValueFor(IntPtr self, IntPtr key)
        public bool HasValueFor(string key)
        {
            wxString wxKey=wxString.SafeNew(key); // support of unicode if compiled in
            return wxStringMap_HasValueFor(this.wxObject, Object.SafePtr(wxKey));
        }

        [DllImport("wx-c")] static extern IntPtr wxStringMap_ValueFor(IntPtr self, IntPtr key)
        public string ValueFor(string key)
        {
            wxString wxKey=wxString.SafeNew(key);
            return new wxString(wxStringMap_ValueFor(this.wxObject, Object.SafePtr(wxKey)));
        }
        #endregion
        #region Public Properties, Indexers
        public string this[string key]
        {
            get
            {
                return this.ValueFor(key);
            }
        }
        #endregion
   }
 }

Manual of the wx.NET   (c) 2003-2011 the wx.NET project at   Get wx.NET at SourceForge.net. Fast, secure and Free Open Source software downloads