NAME
XS::Framework::Manual::recipe03 - XS::Framework basics
DESCRIPTION
Let's assume that there in an external C++ class which follows singleton pattern. Also, let's assume that it returns const
singleton, i.e. all methods of C++ class are marked as const
. Here is an example of such class
struct TimezoneRecipe03 {
const char* get_name() const { return name; }
static const TimezoneRecipe03& get_instance() {
static TimezoneRecipe03* instance = new TimezoneRecipe03();
return *instance;
}
private:
TimezoneRecipe03() { name = "Europe/Minsk"; }
const char* name;
};
It is possible to specialize typemaps with const typemap. Althought, Perl does not have notion of const objects, it has notion of read-only SV*, so invoking non-const method on read-only SV* wrapper leads to cannot modify read-only object
error. Here is an example of typemap
namespace xs {
template <>
struct Typemap<const TimezoneRecipe03*> : TypemapObject<const TimezoneRecipe03*, const TimezoneRecipe03*, ObjectTypeForeignPtr, ObjectStorageIV, StaticCast> {
// (1) (2) (3) (4) (5)
static std::string package () { return "MyTest::Cookbook::TimezoneRecipe03"; }
};
}
Here (1 .. 3) shows how to define typemap for const object. Please, not that non-const typemap is auto-deduced from const typemap.
As the perl side does not owns the pointer, and, hence, does not need to delete
it, we can use ObjectTypeForeignPtr
lifetime policy (4) and ObjectStorageIV
storage policy (5). There is no leak in missing DESTROY
method in xs-adapter below. Please note, that it is assumed that no further class extension is possible (see limitations of ObjectStorageIV
storage policy).
The xs-adapter code should look like:
MODULE = MyTest PACKAGE = MyTest::Cookbook::TimezoneRecipe03
PROTOTYPES: DISABLE
const char* TimezoneRecipe03::get_name() : const;
# (5) (6)
const TimezoneRecipe03* get_instance() { RETVAL = &TimezoneRecipe03::get_instance(); }
# (7)
It is rather trivial; hovewer, please, pay attention to a few nuances: the const
methods should be marked as attribute const
(6) after colon (5). The returned pointer (7) should also be marked with const
.