Boost logo

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