dynamically instantiate a class

S

Sumit Nagpal

Hi All,

My application reads a 'Class' name (as a string) from a file at Run time.
Can i create an instance this Class ?

Thanks
Sumit
 
M

Mike Wahler

Sumit Nagpal said:
Hi All,

My application reads a 'Class' name (as a string) from a file at Run time.
Can i create an instance this Class ?

Sure.

std::string classname;
std::ifstream instream("myfile");
instream >> classname;
myClass *mc = 0;

if(classname == "myClass")
mc = new myClass;

-Mike
 
P

Phlip

Sumit said:
My application reads a 'Class' name (as a string) from a file at Run time.
Can i create an instance this Class ?

Look up Factory Pattern, and Prototype Pattern with Google.com
 
P

Pavel Vozenilek

Sumit Nagpal said:
My application reads a 'Class' name (as a string) from a file at Run time.
Can i create an instance this Class ?
You must add infrastructure: create object factory which
takes string and outputs heap allocated class.

/Pavel
 
M

Michael Kurz

Sumit Nagpal said:
Hi All,

My application reads a 'Class' name (as a string) from a file at Run time.
Can i create an instance this Class ?
No.

Typically you would create a factory or at least a factory method,
which creates an object based on the class name.

Regards
Michael
 
S

Sumit Nagpal

Perhaps I didnt ask my question in properly.

Say, I write some code in core.so and some other person writes plugin.so
& plugin.txt
plugin.txt has a string "MyClass"
plugin.so has the definition of MyClass

While writing core.so I dont know anything about MyClass.

so there is no question of comparing it with something.


please tell me if i am still unclear.

Thanks
Sumit
 
S

Sumit Nagpal

I certainly have to go for FACTORY method but in my case I need
something more...
I think 'dlsym' should work for me !
 
G

Gianni Mariani

Sumit said:
I certainly have to go for FACTORY method but in my case I need
something more...
I think 'dlsym' should work for me !

Warning ... try to steer away from dlsym. This reqyures you to know
what the mangling convention is - this is not portable.

Austria C++ (Shameless plug) has a solution for you and it works with
DLL's or DSO's.

Below is an example.


-------------- test code ------------------

#include "interface.h"

#include "at_factory.h"

using namespace at;


#include <iostream>
#include <dlfcn.h>


void Test( Interface * ptr )
{
if ( ! ptr )
{
std::cout << "There is no ptr\n";
return;
}

std::cout << "Thingy() = " << ptr->Thingy() << "\n";
std::cout << "Thingy1() = " << ptr->Thingy1() << "\n";
std::cout << "Thingy2() = " << ptr->Thingy2() << "\n";

bool is_del = false;

ptr->MarkPtr( & is_del );

delete ptr;

std::cout << ( is_del ? "Deleted" : "Not Deleted" ) << "\n";

}


void testfactory()
{


Interface * ptr =
FactoryRegister< Interface, DKy, Creator1P< Interface, DKy,
const char * > >
::Get().Create( "ImplementorKEY" )( "contructor param" );

Test( ptr );

ptr =
FactoryRegister< Interface, DKy, Creator2P< Interface, DKy,
const char *, const char * > >
::Get().Create( "ImplementorKEY" )( "contructor param1",
"contructor param2" );

Test( ptr );
}

void loaddso()
{
if ( ! dlopen( "xxx_dso.so", RTLD_LAZY ) )
{
std::cerr << "dlopen error is: " << dlerror();
}
}

int main()
{

/* output should be :
There is no ptr
There is no ptr
*/

testfactory();

// load the objects ...
loaddso();

/*output should now be :
Thingy() = contructor param
Thingy1() =
Thingy2() =
Deleted
Thingy() = contructor param1
Thingy1() = contructor param2
Thingy2() =
Deleted
*/

testfactory();

}



------------------- interface.h -------------------------



class Interface
{

public:

virtual const char * Thingy() = 0;
virtual const char * Thingy1() = 0;
virtual const char * Thingy2() = 0;

bool * mark_del;

Interface()
: mark_del( 0 )
{
}

virtual ~Interface()
{
if ( mark_del )
{
* mark_del = true;
}
}

void MarkPtr( bool * i_mark_del )
{
mark_del = i_mark_del;
}

virtual int ContructParamCount() = 0;

};


--------------- implementation code ---- xxx_dso.cpp ----------

#include "interface.h"

#include "at_factory.h"

using namespace at;


class Implementor
: public Interface
{

public:

virtual const char * Thingy()
{
return m_str;
}

virtual const char * Thingy1()
{
return m_str2;
}

virtual const char * Thingy2()
{
return m_str3;
}

Implementor( const char * str, const char * str2, const char *
str3 )
: m_str( str ),
m_str2( str2 ),
m_str3( str3 ),
contruction_parameter_count( 3 )
{
}

Implementor( const char * str, const char * str2 )
: m_str( str ),
m_str2( str2 ),
m_str3( "" ),
contruction_parameter_count( 2 )
{
}

Implementor( const char * str )
: m_str( str ),
m_str2( "" ),
m_str3( "" ),
contruction_parameter_count( 1 )
{
}

Implementor()
: m_str( "" ),
m_str2( "" ),
m_str3( "" ),
contruction_parameter_count( 0 )
{
}

virtual int ContructParamCount()
{
return contruction_parameter_count;
}

int contruction_parameter_count;

const char * m_str;
const char * m_str2;
const char * m_str3;
};


AT_MakeFactory0P( "ImplementorKEY", Implementor, Interface, DKy );
AT_MakeFactory1P( "ImplementorKEY", Implementor, Interface, DKy, const
char * );
AT_MakeFactory2P( "ImplementorKEY", Implementor, Interface, DKy, const
char *, const char * );
AT_MakeFactory3P( "ImplementorKEY", Implementor, Interface, DKy, const
char *, const char *, const char * );
 
M

Michael Kurz

Sumit Nagpal said:
Perhaps I didnt ask my question in properly.

Say, I write some code in core.so and some other person writes plugin.so
& plugin.txt
plugin.txt has a string "MyClass"
plugin.so has the definition of MyClass

While writing core.so I dont know anything about MyClass.

so there is no question of comparing it with something.

So If Iam right that *.so is a dynamic link library on linux (Iam more
familar with the windows stuff: DLL)
You need to export symbols, which can be used:

Thats how COM does it (roughly, adapted to your question):
- Define a Factory Interface (abtract base class), which is able to create
objects by a given class name and returns a pointer to the created object,
as you probably want to create different kinds of objects, of course all
objects created with one factory (factory interface) should share the
(abstract) BaseClass.

-Define an exported function within your *.so / *.dll file, which returns a
pointer to the factory.
(COM: CoGetClassObject), to make this compiler independent you could make
this function with C Linkage (extern "C")

If you want something like:
*.so contains a class, you only know the name nothing else about the class
and you want to create an instance without providing an Interface, well this
will not work with C++.



Regards
Michael
 
K

Karl Heinz Buchegger

Sumit said:
Perhaps I didnt ask my question in properly.

Say, I write some code in core.so and some other person writes plugin.so
& plugin.txt
plugin.txt has a string "MyClass"
plugin.so has the definition of MyClass

While writing core.so I dont know anything about MyClass.

Right.

I would do it this way:
All your plugins contain one class, which represents the plugin.
All those classes are derived from a common base class. All the
core knows about is a collection of pointers to those in order
to route commands to them.
So how then is the real plugin object created?
Simple: Each plugin.so has a function 'Create' which creates
the real plugin object and returns a pointer to it. And the
plugin.so knows about its real class.
 
S

Sumit Nagpal

Yeah but if I do extern 'C' for that particular symbol, there wont be
any name mangling problem.

Thanks
Sumit Nagpal
 
S

Sumit Nagpal

You are right but I was talking about the situations where I'll have
multiple unkown plugins.
Now I have the solution for it 'dlsym' which will allow me to
instantiate all plugin classes with all plugin.so having 'Create' functions.

Thanks
Sumit
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,776
Messages
2,569,603
Members
45,188
Latest member
Crypto TaxSoftware

Latest Threads

Top