WX.Net

About/News
Screenshots

Documentation
    Why WX.Net? 
    Roadmap
    Release Notes
    Building From Source
    Tutorial
    User Manual
    Reference Doc.
    WX.Build Doc.
    wxWidgets

Download

Who's Who
SourceForge

Get WX.Net at SourceForge.net. Fast, secure and Free Open Source software downloads

Built with wxWidgets

Works on Mono

?????????????????????????

How to Contribute

Getting Started

Those wishing to contribute to building the wrapper should start with creating a simple wrapper for a test class, then read about using the generator script.

Adding Wrappers for C++ Classes

In the following steps, a wrapper for the following C++ class will be created (test.h):

class Test
{
public:
    Test() { value = 0; }
    ~Test() {}

    int GetValue() { return value; }
    void SetValue(int val) { value = val; }

private:
    int value;
};
  • Write a C wrapper for the class. This usually consists of creating a C function for every C++ function. To simulate the this pointer, an instance of the class is passed to each C function. Here is test.cxx:

    #include <wx/wx.h>
    #include <test.h>

    // Constructor for the Test constructor
    extern "C" WXEXPORT Test* Test_ctor()
    {
        return new Test();
    }

    // Wrapper for Test::GetValue()
    extern "C" WXEXPORT int Test_GetValue(Test* self)
    {
        return self->GetValue();
    }

    // Wrapper for Test::SetValue();
    extern "C" WXEXPORT void Test_SetValue(Test* self, int val)
    {
        self->SetValue(val);
    }

    // Wrapper for the Test destructor
    extern "C" WXEXPORT void Test_dtor(Test* self)
    {
        delete self;
    }
  • In the case of WX.Net, this wrapper would be added to the Src/wx-c/ directory. To add the file to the build script, modify premake.lua, and add the file to the package.files variable. Use Premake to re-create the build system after modifying premake.lua.

  • The corresponding C# wrapper would have a DllImport statement for each of the C functions. The C# wrapper would also have a member variable corresponding to the C++ this pointer of type IntPtr.

    In WX.Net, this pointer is a protected member of the class wx.Object, so the Test class in C# will inherit from Object. Object::wxObject is the IntPtr that refers to the external class pointer.

    Test.cs is as follows:

    using System;

    // InteropServices provides functionality for interacting with external
    // systems.
    using System.Runtime.InteropServices;

    namespace wx
    {
        public class Test : Object
        {
            // Import the constructor.  It returns the IntPtr used to set
            // wxObject.  'wx-c' refers to the shared object or DLL that will
            // be loaded at runtime.
            [DllImport("wx-c")] static extern IntPtr Test_ctor();

            // Test::GetValue and Test::SetValue.
            [DllImport("wx-c")] static extern int Test_GetValue(IntPtr self);
            [DllImport("wx-c")] static extern void Test_SetValue(IntPtr self, int val);

            // Test destructor.
            [DllImport("wx-c")] static extern void Test_dtor(IntPtr self);


            // C# constructor - initializes the base class with a new pointer
            // returned from the constructor wrapper.
            public Test()
                : base(Test_ctor())
            {
            }

            // In C#, Get/Set methods can be contained in a property.
            public int Value
            {
                get
                {
                    // Object::wxObject is passed as 'self' and is used by the
                    // C wrapper.
                    return Test_GetValue(wxObject);
                }

                set
                {
                    Test_SetValue(wxObject, value);
                }
            }

            // Test destructor.
            public ~Test()
            {
                Test_dtor(wxObject);
            }
        }
    }
  • In WX.Net, the C# interface files are placed in the Src/WX.Net directory. Add the appropriate line to premake.lua in this directory for the newly added Test.cs, as was done in step 2. Rebuild the build system.

After recompiling, the wrapper is complete, and the Test C++ class can now be used from C#.

The following is a list of hints to help you along with various problems:

  • To pass wxPoint or wxSize objects, use the C# System.Drawing namespace Size and Point classes. See the existing source files for examples of this.

  • When passing other wx.* objects, the use of the Object.SafePtr() method is recommended. This method ensures that a null pointer is passed correctly to the C wrapper.

Refer also to the documentation of the
wx.Object
class API description.

Using the C Wrapper Generation Script

Included in the Src/wx-c-gen directory is wx-c-gen.pl. This Perl script is meant to create a template to help minimalize the amount of work involved with creating a C# wrapper.

The script parses the C++ header files located in the wxWidgets include directory, and outputs a C wrapper, as well as a C# stub with DllImport statements for interacting with the C wrapper.

The generated files are not perfect, and the parsing method that the script uses is erronous; however, the generated files do save a fair amount of time.

To use script, first edit it, and modify the $HEADER_DIR and $OUTPUT_DIR variables to suite your needs. Create the output directories as necessary, then execute the script using the following command:

> ./wx-c-gen.pl generate

After generating, the files will be placed in the output directory specified, and are ready for template use.