|
Boost : |
From: Stefan Roiser (stefan.roiser_at_[hidden])
Date: 2006-01-31 03:59:40
On 30 Jan 2006, at 23:55, Stefan Seefeld wrote:
> Stefan Roiser wrote:
>
>
>> Reflex code for this would look something like
>>
>> Type t = Type::ByName("foo");
>> Object instance = t.Construct();
>
> That clearly only works if 'foo' has a default constructor, right ?
You are right, the above code snippet has a lot of assumptions (e.g.
we found a dictionary for type foo, foo has a default constructor
etc.), please see below for a bit more safe implementation.
> Even then, it may involve some other resources to be set up. So, what
> knowledge of the code being invoked that way do you require ?
Reflex would need a dictionary for class "foo" (generated by
genreflex.py with gccxml). So something like
python genreflex.py foo.h --gccxmlpath=/path/to/gccxml/bin
will generate a file foo_rflx.cpp with the dictionary information
about class foo.
This file will contain all the information necessary to introspect/
interact with foo
and can be compiled into a shared library libfoo.so
> Who
> would provide the implementation for 'foo', who would provide
> the above lines, and who would finally execute them ?
I'm assuming that class foo is a class for which the dictionary is
generated and subsequently a user want's to introspect/interact with
its dictionary information.
So a bit more safe implementation of the lines above would be
// load dynamically library libfoo.so
Type t = Type::ByName("foo");
if (t && t.IsClass()) {
// we found the dictionary information for "foo" and it's a class
// let's try to call the default constructor
// Construct has several default arguments, by default it will try
to invoke the default constructor
Object instance = t.Construct();
if (instance) {
// we have a valid instance (memory allocated, type associated)
// we have constructed an instance through the default constructor
}
else {
// this class does not have a default constructor
// let's loop over all constructors and look for one which takes
e.g. one int as argument
for (Member_iterator mi = t.FunctionMember_Begin(); mi !=
t.FunctionMember_End(); ++mi) {
if ((*mi).IsConstructor()) {
Type constType = (*mi).TypeOf();
if (constType.FunctionParameterSize() == 1 &&
constType.FunctionParameterAt(0).TypeOf().Name() == "int") {
// let's invoke this constructor with one argument (this
has to be passed in a vector<void*>)
int arg0 = 111;
std::vector<void*> args;
args.push_back(&arg0);
instance = t.Construct(constType,args);
.......
Cheers
Stefan
-- Stefan Roiser CERN, PH Department CH - 1211 Geneva 23 Mob:+41 76 487 5334 Tel:+41 22 767 4838 Fax:+41 22 767 9425
Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk