wxLuaBinding 2.8.10 - Writing and Generating Binding Files

The binding generator for wxLua provides information for Lua code to interface to a C/C++ API. The C/C++ objects are created in Lua as userdata and manipulated using the same functional semantics as you would in C/C++. The wxlua.html wxLua documentation describes in detail how the object will be named and where it will be placed in Lua.

Binding files are provided for the wxWidgets cross platform GUI library and the wxStyledTextCtrl contrib library of the wxWidgets library. You may also write and add your own bindings to use wxLua as a scripting language in your own C++ project. There is an example of this in the apps/wxluacan/src directory.

The interface files are skeletons of the C/C++ header files that the program bindings/genwxbind.lua parses and turns into C functions that are imported into Lua by an automatically generated wxLuaBinding derived class. The whole process of generation is automatic and no editing of the output files should be required. If there is any problem you should fix the interface files and regenerate instead of trying to fix the generated files. Some examples of the interface files are in the bindings/wxwidgets/*.i directory. Before writing your own, take some time to examine them to see the differences between them and the original C++ code. If the automatic bindings do not generate suitable code for a specific function, you can %override individual function bindings with your own code to implement it in any way you want.

Contents

  1. Binding File Descriptions
  2. Generated Files
  3. Binding C++ Virtual Functions
  4. Interface File Constructs
    1. Special Function Parameters
    2. C++ Class Member Function Directives
    3. Comments
    4. Interface Tags

Binding File Descriptions

bindings/genwxbind.lua

*.i interface files

*_datatypes.lua files

wxluasetup.h

overrides.hpp

Generated Files

The binding generator genwxbind.lua generates a number of files and you can specify both their names and directories.

Binding C++ Virtual Functions

The only way to handle C++ virtual functions in wxLua is to subclass the C++ class you want to be able to write Lua functions for and bind the subclassed version. The hand coded wxLuaPrintout class is a good example of this, let's examine how the code in C++ and Lua works to allow you to override a C++ virtual function.
The wxWidgets class wxPrintout has a number of virtual functions, but lets focus on "virtual bool wxPrintout::OnBeginDocument(int startPage, int endPage)" as an example, since if you override this function you must also call the base class function for printing to operate correctly. The source code for the class wxLuaPrintout located in modules/wxbind/include/wxcore_wxlcore.h and modules/wxbind/src/wxcore_wxlcore.cpp and you should review it before reading further. You will also need to look at samples/printing.wx.lua to see the Lua code that overrides the function and modules/wxlua/src/wxlbind.cpp for the metatable functions Lua uses to handle a call to a function.
Below is a list of the function calls for wxPrintout::OnBeginDocument and notes about how it all works.
  1. Create a userdata wxLuaPrintout in Lua, replace the function OnBeginDocument with our own one in Lua, and begin the printing process, perhaps doing a print preview? The code for this is in the printing.wx.lua sample.
  2. The wxWidgets printing framework calls virtual wxPrintout::OnBeginDocument(...), but we've subclassed wxPrintout and so the the function wxLuaPrintout::OnBeginDocument(...) gets called.
  3. In wxLuaPrintout::OnBeginDocument() we first check to see if wxLuaState::GetCallBaseClassFunction() is true, if not then check to see if wxLuaState::HasDerivedMethod(this, "OnBeginDocument") is true, where this is the particular instance of the wxLuaPrintout class.
  4. Here's the tricky part for Lua derived functions that then call the base class function. In this case we're not calling the "base" class function of wxLuaPrintout, but rather wxPrintout since wxLuaPrintout is a hollow shell that merely forwards calls to Lua or to the base class.
To summarize, here's the function calls and where in each function wxLuaPrintout::OnBeginDocument is when you override the function in Lua.
  1. wxWidgets calls wxLuaPrintout::OnBeginDocument(...) in C++
  2. wxLuaPrintout::OnBeginDocument(...) runs the code to call the derived Lua function OnBeginDocument by calling wxLuaState::LuaCall on it. (GetCallBaseClassFunction() and HasDerivedMethod() are both true)
  3. wxluabind__index_wxLuaBindClass(...) is called when in Lua the function "_OnBeginPrinting" is called for the wxLuaPrintout userdata, the flag wxLuaState::GetCallBaseClassFunction is set to true, and the C function wxLua_wxPrintout_OnBeginDocument (in modules/wxbind/src/wxcore_print.cpp) is run by Lua which calls back to wxLuaPrintout::OnBeginDocument(...).
  4. We enter wxLuaPrintout::OnBeginDocument(...) a second time, the first time through is still stalled at wxLuaState::LuaCall() running Lua's OnBeginDocument() function, but this time we just call wxPrintout::OnBeginDocument() and return.
  5. The wxLuaState::LuaCall() function finishes and the first call to the function wxLuaPrintout::OnBeginDocument(...) returns.
  6. Success!

Interface File Constructs

Special Function Parameters

C++ Class Member Function Directives

Comments

Interface Tags

%alias
Reference a class by another name (currently unused).

%class [%delete] [%noclassinfo] [%encapsulate] ClassName [, BaseClassName]
ClassName(...)
member functions
%endclass
%define NUMBER [Value]
%define_event wxEVT_XXX
%define_object OBJECT
%define_pointer POINTER
%define_string STRING [Value]
%enum [Enum_Type] or [ClassName::Enum_Type]
ENUM_ITEM1
ENUM_ITEM2
...
%endenum
%function FUNCTION(int value, ...)
%gc
%gc_this
%if wxLUA_USE_XXX & %__WXMSW__
Interface file data...
%endif wxLUA_USE_XXX
%include "headerfile.h"
%includefile interfacefile.i - DEPRECATED and probably does not work
%member int m_x
%member_func int m_x
%operator bool operator==(const wxPoint& otherPt) const
%not_overload int FUNC_NAME(int value)
%override wxLua_ClassName_FunctionName
// any code or comments can go within the %override ... %end block
static int LUACALL wxLua_ClassName_FunctionName(lua_State* L)
{
...
}
%end
%override_name CFunctionNameTheOverrideUses
%property NAME, read, write
%rename NEW_FUNC_NAME void FUNC_NAME()
%skip
%typedef KNOWN_DATATYPE UNKNOWN_DATATYPE %ungc
%ungc_this
%wxchkver_X_Y_Z
%wxcompat_X_Y
These #ifdef conditions are deprecated, use __XXX__ conditions directly
%msw - the next item will #if defined(__WXMSW__)
%gtk
- the next item will #if defined(__WXGTK__)
%mac
- the next item will #if defined(__WXMAC__)
%win
- the next item will #if defined(__WXMSW__)
%mgl - the next item will #if defined(__WXMGL__)
%motif
- the next item will #if defined(__WXMOTIF__)
%univ
- the next item will #if defined(__WXUNIVERSAL__)
%x11
- the next item will #if defined(__WXX11__)
%cocoa
- the next item will #if defined(__WXCOCOA__)
%os2
- the next item will #if defined(__WXPM__)
%palm
- the next item will #if defined(__WXPALMOS__)
%wince
- the next item will #if defined(__WXWINCE__)

Standard wxWidgets #defines for conditional use using the %if directive
%__WINDOWS__
%__WIN16__
%__WIN32__
%__WIN95__
%__WXBASE__
%__WXCOCOA__
%__WXWINCE__
%__WXGTK__
%__WXGTK12__
%__WXGTK20__
%__WXMOTIF__
%__WXMOTIF20__
%__WXMAC__
%__WXMAC_CLASSIC__
%__WXMAC_CARBON__
%__WXMAC_OSX__
%__WXMGL__
%__WXMSW__
%__WXOS2__
%__WXOSX__
%__WXPALMOS__
%__WXPM__
%__WXSTUBS__
%__WXXT__
%__WXX11__
%__WXWINE__
%__WXUNIVERSAL__
%__X__
%__WXWINCE__