www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - RTTI : how to create object from name

reply LiuXuHong <LiuXuHong_member pathlink.com> writes:
// It's easy to create object using the RTTI mechanism in D. e.g.

class AAA {} // actually it derived from Object

// we can create AAA like this, classinfo is a static member of AAA
AAA a = cast(AAA)cast(void*)AAA.classinfo.init;

// but how can we create AAA just use the class name "AAA", like this

AAA a1 = someImpementation("AAA");



I am from Shanghai, China.
Nice to meet you here :)
Oct 26 2004
next sibling parent Stewart Gordon <smjg_1998 yahoo.com> writes:
LiuXuHong wrote:

 // It's easy to create object using the RTTI mechanism in D. e.g.
 
 class AAA {} // actually it derived from Object
 
 // we can create AAA like this, classinfo is a static member of AAA
 AAA a = cast(AAA)cast(void*)AAA.classinfo.init;

Surely that isn't creating an AAA, but creating a reference to a static AAA?
 // but how can we create AAA just use the class name "AAA", like this
 
 AAA a1 = someImpementation("AAA");

AIUI you can't do it directly. But you could create an associative array listing all the classes in your app that are going to be subjectable to this behaviour.... Is this for anything particular? Stewart.
Oct 26 2004
prev sibling next sibling parent reply h3r3tic <foo bar.baz> writes:
LiuXuHong wrote:
 // It's easy to create object using the RTTI mechanism in D. e.g.
 
 class AAA {} // actually it derived from Object
 
 // we can create AAA like this, classinfo is a static member of AAA
 AAA a = cast(AAA)cast(void*)AAA.classinfo.init;
 
 // but how can we create AAA just use the class name "AAA", like this
 
 AAA a1 = someImpementation("AAA");

here's my solution to the problem... I have the objfactory.d file: // ----------------------------------------------------- // do not instantiate this struct. it's meant to be >>The ONE<< struct factory { static Object function()[char[]] n2o; static char[][ClassInfo] o2n; class type(T) { static Object createObj() { return new T; } this() { factory.n2o[T.classinfo.name] = &createObj; factory.o2n[T.classinfo] = T.classinfo.name; } this(char[] name) { factory.n2o[name] = &createObj; factory.o2n[T.classinfo] = name; } } char[] nameOf(Object obj) { return o2n[obj.classinfo]; } static Object make(char[] name) { if ( name in n2o ) return n2o[name](); else throw new Error("unknown class requested from the factory: " ~ name); } } // -------------------------------------------------------- Now you can register some types into the factory with: new factory.type!(Foo); new factory.type!(Bar)("main.bar"); new factory.type!(Baz); e.g. in the module's static ctor. Objects are created with: Object result = factory.make(name); Hope this helps Tom
Oct 26 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
h3r3tic wrote:
<snip>
 I have the objfactory.d file:
 // -----------------------------------------------------
 // do not instantiate this struct. it's meant to be >>The ONE<<

Then why bother making it a struct? Why not just a module? Stewart.
Oct 27 2004
parent reply h3r3tic <foo bar.baz> writes:
Stewart Gordon wrote:
 h3r3tic wrote:
 <snip>
 
 I have the objfactory.d file:
 // -----------------------------------------------------
 // do not instantiate this struct. it's meant to be >>The ONE<<

<snip> Then why bother making it a struct? Why not just a module? Stewart.

So that one's forced to access this struct's members using 'factory.' e.g. this is ok: new factory.type!(Foo); but this gives an error: new type!(Foo); Or can that be done with a module as well ? :>
Oct 27 2004
parent reply Stewart Gordon <smjg_1998 yahoo.com> writes:
h3r3tic wrote:
<snip>
 So that one's forced to access this struct's members using 'factory.'
 e.g. this is ok: new factory.type!(Foo);
 but this gives an error: new type!(Foo);
 
 Or can that be done with a module as well ? :>

If you think new type!(Foo); isn't long enough to prevent accidents, give the class a longer name. Otherwise, what's the point? Stewart.
Oct 27 2004
parent h3r3tic <foo bar.baz> writes:
Stewart Gordon wrote:
 h3r3tic wrote:
 <snip>
 
 So that one's forced to access this struct's members using 'factory.'
 e.g. this is ok: new factory.type!(Foo);
 but this gives an error: new type!(Foo);

 Or can that be done with a module as well ? :>

If you think new type!(Foo); isn't long enough to prevent accidents, give the class a longer name. Otherwise, what's the point? Stewart.

Whatever... that's just a philosophical choice...
Oct 28 2004
prev sibling parent "Ben Hinkle" <bhinkle mathworks.com> writes:
"LiuXuHong" <LiuXuHong_member pathlink.com> wrote in message
news:clm0co$2qcm$1 digitaldaemon.com...
 // It's easy to create object using the RTTI mechanism in D. e.g.

 class AAA {} // actually it derived from Object

 // we can create AAA like this, classinfo is a static member of AAA
 AAA a = cast(AAA)cast(void*)AAA.classinfo.init;

 // but how can we create AAA just use the class name "AAA", like this

 AAA a1 = someImpementation("AAA");



 I am from Shanghai, China.
 Nice to meet you here :)

Here's something that doesn't work but maybe some can fix it so that it does. The GetProcAddress always returns null for me - maybe the symbol doesn't exist or isn't exported or maybe I'm poking at the wrong symbol. I don't know. module reflect; import std.loader; import std.string; import std.c.windows.windows; extern (C) Object _d_newclass(ClassInfo ci); // no ctor called - just inited! Object newInstance(char[] name) { char[] mangled; HMODULE exe = GetModuleHandleA(null); // get executable while (name.length > 0) { int dot = find(name,'.'); if (dot != -1) { mangled ~= toString(dot) ~ name[0 .. dot]; name = name[dot+1 .. name.length]; } else { mangled ~= toString(name.length) ~ name; name = ""; } } mangled = "__Class_" ~ mangled; FARPROC ptr = GetProcAddress(exe,mangled); printf("ptr = %p\n",ptr); return _d_newclass(cast(ClassInfo)ptr); } class AAA { int x; } int main() { Object a = newInstance("reflect.AAA"); return 0; }
Oct 26 2004