| C++/Tcl A C++ library for interoperability between C++ and Tcl |
i.def("fun", fun);fun, is enough for the C++/Tcl
libray to discover the following information:SomeClass * produce(){ return new SomeClass();}void consume(SomeClass *p){ // ... delete p;}i.def("produce", produce);i.def("consume", consume);% set object [produce]p0x807b790% consume $objectproduce command will not register
any new Tcl command that would be responsible for managing member
function calls or explicit object destruction, because, simply, it has
no idea to which class definition (in the Tcl sense, not the C++ sense)
the returned object belongs. In other words, the object name that is
returned by the produce command has no meaning to the Tcl
interpreter.produce function:i.def("produce", produce,
factory("SomeClass"));factory policy above provides the following
information:produce function are
created with the new expression, or by other means. In
any case - the pointer is returned."SomeClass"
Tcl class.-delete method. This call does two things:deletes the objects (in the C++ sense), andconsume() function does the
first thing. It is important also to do the second, otherwise the Tcl
interpreter will be polluted with commands associated with non-existent
objects (any call to such a command will result in undefined behaviour,
which usually means a program crash).consume() function is a sink for objects:i.def("consume", consume,
sink(1));sink policy above says:consume function takes responsibility for
objects that are passed by its first (1) parameter.// example5.cc#include "cpptcl.h"#include <string>using namespace std;using namespace Tcl;class Person{public: Person(string const &n) : name(n) {} void setName(string const &n) { name
= n; } string getName() { return name; }private: string name;};// this is a factory functionPerson * makePerson(string const &name){ return new Person(name);}// this is a sink functionvoid killPerson(Person *p){ delete p;}CPPTCL_MODULE(Mymodule, i){ // note that the Person class is exposed
without any constructor i.class_<Person>("Person", no_init)
.def("setName", &Person::setName)
.def("getName", &Person::getName); i.def("makePerson", makePerson, factory("Person")); i.def("killPerson", killPerson, sink(1));}% load ./mymodule.so % set p [Person "Maciej"]invalid command name "Person"% Person has no constructor (this
is the effect of providing the no_init policy when the
class was exposed).% set p [makePerson "John"]p0x807b810% $p getNameJohn% % killPerson $p% $p getNameinvalid command name "p0x807b810"% ClassA * create(int i, ClassB
*p1, string const &s, ClassC *p2){ // consume both p1 and p2 pointers // and create new object: return new ClassA();}factory policy, because it returns new objects.sink policy on its second parameter.sink policy on its fourth parameter.i.def("create", create,
factory("ClassA").sink(2).sink(4));factory policy can be
related to only one class, so it is the last factory
policy in the chain that is effective.object
const &
variadic() policy must be provided when
defining that function.object type
and it allows to retrieve both single values and lists.void fun(int a, int b, object const &c);
// later:
i.def("fun", fun);void fun(int a, int b, object const &c);
// later:
i.def("fun", fun, variadic());variadic() policy, the function will accept:c
parameter will be an empty objectc will have the
value of the third argumentc will be a list of all arguments except the
first two integer values.class MyClass{public: MyClass(int a, object const &b); void fun();};// later:i.class_<MyClass>("MyClass", init<int, object const &>(), variadic()) .def("fun", &MyClass::fun);object
const & and that the variadic() policy was
provided.class MyClass{public: void fun(object const &a);};// later:i.class_<MyClass>("MyClass") .def("fun", &MyClass::fun, variadic());variadic() policy may be combined (in any order) with
other policies.#include "cpptcl.h"using namespace Tcl;int sumAll(object const &argv){ interpreter i(argv.get_interp(), false); int sum = 0; size_t argc = argv.length(i); for (size_t indx = 0; indx != argc;
++indx) { object
o(argv.at(i, indx)); sum +=
o.get<int>(i); } return sum;}CPPTCL_MODULE(Mymodule, i){ i.def("sum", sumAll, variadic());}% load ./mymodule.so % sum0% sum 55% sum 5 6 718%