wxWidgets/docs/tech/tn0020.txt

177 lines
6.0 KiB
Plaintext
Raw Normal View History

Binary Compatability and wxWidgets
==================================
0. Purpose
----------
This is broad technote covering all aspects of binary compatability with
wxWidgets.
1. Releases
-----------
General overview of releases can be found in tn0012.txt, but for
completeness the wxWidgets release version number is as follows:
2.6.2
Where
2 6 2
Major Minor Release
(I.E. Major.Minor.Release).
All Release versions where the Minor is EVEN (2.4.x,2.6.x
etc. ODD minors are development versions) are expected to be binary
compatable. Note that this means FORWARD binary compatability only -
new methods to classes are ok as long as they arn't virtual, etc.
2. What kind of changes are NOT binary compatable
-------------------------------------------------
If its still up, the KDE guide is a good reference:
http://developer.kde.org/documentation/other/binarycompatibility.html
The changes that are NOT binary compatable:
- Adding a virtual function
- Changing the name of a any function or variable
- Changing the signature of a virtual function (adding a parameter,
even a default one)
- Changing the order of the virtual functions in a class
["switching" them, etc.]
- Changing access privalages to a function (protected to private etc.)
[unlike KDE we need to support windows so this is not allowed]
- Adding a member variable
- Changing the order of non-static member variables
3. wxABI_VERSION and BACKWARD binary compatability
--------------------------------------------------
As mentioned we do not support BACKWARD binary compatability.
However, for this purpose we have the macro wxABI_VERSION. All
new symbols added to binary compatable releases are to be ifed
with wxABI_VERSION.
The layout of wxABI_VERSION is as follows:
20602
where
20 60 2
Major Minor Release
I.E. it corresponds to the wxWidgets release in {1}.
An example of using wxABI_VERSION is as follows for symbols
only in a 2.6.2 release:
#if wxABI_VERSION >= 20602 /* 2.6.2+ only */
bool Load(const wxURI& location, const wxURI& proxy);
wxFileOffset GetDownloadProgress();
wxFileOffset GetDownloadTotal();
bool ShowPlayerControls(
wxMediaCtrlPlayerControls flags =
wxMEDIACTRLPLAYERCONTROLS_DEFAULT);
//helpers for the wxPython people
bool LoadURI(const wxString& fileName)
{ return Load(wxURI(fileName)); }
bool LoadURIWithProxy(const wxString& fileName, const wxString& proxy)
{ return Load(wxURI(fileName), wxURI(proxy)); }
#endif
4. Workarounds for adding virtual functions
-------------------------------------------
Originally the idea for adding virtual functions to binary compatable
releases was to pad out some empty "reserved" functions and then
rename those later when someone needed to add a virtual function.
However, after there was some actual testing of the idea a lot of
controversy erupted. Eventually we decided against the idea, and
instead devised a new method for doing so called wxShadowObject.
wxShadowObject is a class derived from wxObject that provides a means
of adding functions and/or member variables to a class internally
to wxWidgets. It does so by storing these in a hash map inside of
it, looking it up when the function etc. is called. wxShadowObject
is generally stored inside a reserved member variable.
wxShadowObject resides in include/wx/clntdata.h.
To use wxShadowObject, you first call AddMethod or AddField with
the first parameter being the name of the field and/or method
you want, and the second parameter being the value of the
field and/or method.
In the case of fields this is a void*, and in the case of method
is a wxShadowObjectMethod which is a typedef:
typedef int (*wxShadowObjectMethod)(void*, void*);
After you add a field, you can set it via SetField with the same
params as AddField, the second param being the value to set
the field to. You can get the field after you call AddField
via GetField, with the parameters as the other two field functions,
only in the case the second parameter is the fallback
value for the field in the case of it not being found in the
hash map.
You can call a method after you add it via InvokeMethod, which
returns a bool indicating whether or not the method was found
in the hash map, and has 4 parameters. The first parameter is
the name of the method you wish to call, the second is the first
parameter passed to the wxShadowObjectMethod, the third is the
second parameter passed to that wxShadowObjectMethod, and the
fourth is the return value of the wxShadowObjectMethod.
5. version-script.in
--------------------
For ld/libtool we use sun-style version scripts. Basically
anything which fits the conditions of being ifed via wxABI_VERSION
needs to go here also.
The file has the layout as follows:
@WX_VERSION_TAG@.X
Where X is the current Release as mentioned earlier, i.e. 2. This
is following by an opening bracket "{", followed by "global:",
followed by the added symbols, then followed by "}", and then
the file is either followed by earlier Releases or ended by
a @WX_VERSION_TAG@ block without the period or Release.
Added symbols have the form
*CLASSNAME*METHODNAME*PARAM1*PARAM2*...
Where CLASSNAME is the name of the class or blank (along with
omitted *) in the case of a global function. METHODNAME is the name
of the class method or global function. This is followed by another
star "*" and then the type of each subsequent parameter for the function,
such as *wxString etc..
6. Testing binary compatability between releases
------------------------------------------------
An easy way of testing binary compatability is just to build wxWidgets
in dll/dynamic library mode and then switch out the current library
in question with an earlier stable version of the library, then running
the application in question again. If it runs OK then there is usually
binary compatability between those releases.
You can also break into your debugger or whatever program you want
to use and check the memory layout of the class. If it is the same
then it is binary compatable.
=== EOF ===
Author: RN
Version: $Id$