digitalmars.D - RTTI : how to create object from name
- LiuXuHong (8/8) Oct 26 2004 // It's easy to create object using the RTTI mechanism in D. e.g.
- Stewart Gordon (7/16) Oct 26 2004 AIUI you can't do it directly. But you could create an associative
- h3r3tic (49/59) Oct 26 2004 here's my solution to the problem...
-
Stewart Gordon
(5/8)
Oct 27 2004
- h3r3tic (5/17) Oct 27 2004 So that one's forced to access this struct's members using 'factory.'
- Stewart Gordon (7/12) Oct 27 2004 If you think
- h3r3tic (2/20) Oct 28 2004 Whatever... that's just a philosophical choice...
- Ben Hinkle (37/45) Oct 26 2004 Here's something that doesn't work but maybe some can fix it so that it
// 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
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
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
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.
Oct 27 2004
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 ? :>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.
Oct 27 2004
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
Stewart Gordon wrote:h3r3tic wrote: <snip>Whatever... that's just a philosophical choice...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 28 2004
"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