Wx::NewClass(3pm)
π Wx::NewClass β adding a new class to wxPerl β¨
okay bestie, welcome to Wx::NewClass, a page from the User Contributed Perl Documentation era that teaches you how to add a whole new class to wxPerl. yes, you. you're gonna wrap a C++ class and make it live in Perl. iconic behavior. π«Ά
πΈ CHECKLIST πΈ
before you do ANYTHING, vibe check yourself against these:
- Are there constants or events that need to be wrapped?
β see "CONSTANTS" and "EVENTS".
- Is the class is derived from
wxObject, fromwxEvtHandleror from another class?
β see "CHOOSING A TYPEMAP".
- Are class instances destroyed by wxWidgets or should they be garbage collected like normal Perl objects?
β see "DESTRUCTORS AND THREADS".
- Does the class have overloaded methods?
β see "OVERLOADING".
- Does the class have virtual methods that should be overridable from Perl?
β see "VIRTUAL METHODS".
π SKELETON π
step one, gorgeous: add a new file XS/NewClass.xsp and update the MANIFEST. (yes, actually update it, don't ghost the MANIFEST, she notices.)
then pick a relevant .xs file in the top level directory (like, say, Controls.xs) and slide this line into it:
INCLUDE_COMMAND: $^X -MExtUtils::XSpp::Cmd -e xspp -- -t typemap.xsp XS/NewClass.xsp
and here's your little starter pack for NewClass.xsp:
%module{Wx};
#include <wx/newclass.h> // use the relevant wxWidgets header(s)
%name{Wx::NewClass} class wxNewClass : public wxSomeBaseClass
{
# constructors see the CONSTRUCTORS section
wxNewClass( wxWindow* some_window, const wxString& str );
# destructors
~wxNewClass();
# methods
wxString GetString() const;
void SetString( const wxString& str );
};
then add the typemap definition to typemap.tmpl. which one tho?? β "CHOOSING A TYPEMAP" has you. π
and hmm, if you're adding a class related to one of the wxPerl submodules ("Wx::RichText", "Wx::Html", ...) then you do it different: drop the .xsp file into the relevant subdirectory and modify the .xs and typemap files in that subdirectory. stay in your lane (affectionately). π¦
π CHOOSING A TYPEMAP π
there are five typemaps that should work for most wxWidgets objects, and choosing the right one is literally the whole game:
- "O_NON_WXOBJECT" β for all classes that do not derive from
wxObjectAND do not need to be garbage collected. - "O_NON_WXOBJECT_THR" β for all classes that do not derive from
wxObjectAND need to be garbage collected (peep "DESTRUCTORS AND THREADS"). - "O_WXOBJECT" β for all classes that derive from
wxObjectAND do not need to be garbage collected. - "O_WXOBJECT_THR" β for all classes derived from
wxObjectAND need to be garbage collected (again: "DESTRUCTORS AND THREADS"). - "O_WXEVTHANDLER" β for all classes that derive from
wxEvtHandler. also go look at "CONSTRUCTORS".
β¨ CONSTRUCTORS β¨
so for O_WXEVTHANDLER typemaps there's extra code you gotta sprinkle into the constructor. like this:
wxNewClass( wxWindow* some_window, const wxString& str )
%code{% RETVAL = new wxNewClass( some_window, str );
wxPli_create_evthandler( aTHX_ RETVAL, CLASS );
%};
no notes, just vibes and a %code% block. π
π DESTRUCTORS AND THREADS π
okay bestie this is the part where it gets real. for MANY classes not derived from wxEvtHandler you need to add a destructor to free the C++ object when the Perl object gets garbage collected. at the XS++ level that means adding
~wxNewClass();
to the class definition. but here's the catch (and it's a big one): the Perl threading model. π
without going into the whole lore, this stuff is needed for Perl threads compatibility:
- Use the correct typemap β choose either
O_NON_WXOBJECT_THRorO_WXOBJECT_THR. - Implement a
CLONEmethod β add this code inside the class declaration:
%{
static void
wxNewClass::CLONE()
CODE:
wxPli_thread_sv_clone( aTHX_ CLASS, (wxPliCloneSV)wxPli_detach_object );
%}
- Fix the destructor β modify the destructor like this:
~wxNewClass()
%code%{ wxPli_thread_sv_unregister( aTHX_ "Wx::NewClass", THIS, ST(0) );
delete THIS;
%};
π§ VIRTUAL METHODS π§
good news!! wrapping virtual functions whose arguments are simple C++ types (integrals, bool, floating point) and common wxWidgets types (wxString) should be automatic. the wrapping does itself. main character energy fr fr. π
first, at the top of the file, load the plugin that handles virtual methods:
%loadplugin{build::Wx::XSP::Virtual};
then decorate your virtual/pure virtual methods using the %Virtual directive:
// pure virtual
virtual wxString GetTitle() const = 0 %Virtual{pure};
// virtual, not pure
virtual int GetBestFittingWidth(unsigned int idx) const %Virtual;
heads up: if the class contains pure virtual methods, it will be marked as abstract, and it will have no constructors. π«
and for abstract classes, XS++ will create an additional Perl-level class called Wx::Pl<classname>. so to override the virtual methods you must derive from that class β not from Wx::<classname>. don't get it twisted. π
β TODO (aka the "we'll get to it bestie" pile) β
- TODO allow changing the default behaviour for abstract/concrete classes
- TODO allow overriding the class name
- TODO allow specifying custom code
- TODO handle multiple return values
- TODO customized type mapping
that's the whole page, angel. now go forth and wrap a class. slay. π©·
written against the docs from perl v5.42.3, dated 2026-08-20, and shipped as Wx::NewClass(3pm) under User Contributed Perl Documentation. bye bestie π
π¦ where this page comes from
- ubuntu stonking: libwx-perl 1:0.9932-10build2 Β· Artistic-1.0-Perl OR GPL-1.0-or-later
- π girlified by deepseek-ai/DeepSeek-V4.1-Flash on : a language model's rewrite of the original, under its terms