Is it possible to dlopen the running executable (for purposes of classloading)

Sage
Posts: 1,199
Joined: 2004.10
Post: #1
I have a hacky C++ classloader -- which is to say, I have a simplistic mechanism where I've mapped classnames to factory functions. Such that I can call:

Code:
Factory::instance()->create( "SkyDome" );

And that's great. But, for the factory to work, I've got to define a factory function ( just a function which returns a new instance of a certain class ), and I've got to register it with the factory class, as such:

Code:
Factory *f = Factory::instance();
f->registerFactory( "SkyDome", SkyDome_create );
f->registerFactory( "CelestialBody", CelestialBody_create );
f->registerFactory( "Terrain", Terrain_create );
//...
// and so on, and so on. Ad nauseam.

So I was thinking, what if I dlopen'ed my running executable and attempted to dlsym the factory function? I know darwin doesn't have a dlopen, but the dlcompat library has worked for me to "simulate" dlopen quite effectively.

The problem is, I get a dlerror() message that the file ( the running executable ) is not a library. Which I suppose is true. But I *know* I've seen configure scripts output "yes" for "executable can dlopen itself".

Here's the project ( it includes dlcompat )
http://zakariya.net/shamyl/ClassLoader.zip

Can anybody help me figure out how to make this work? Perhaps I need to use something closer to Darwin to open and resolve symbols in an executable ( as opposed to a library)? Perhaps there's some magic gcc param which will suddenly allow my app to be considered "dlopenable"?

Thanks,
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #2
So, thanks to help from the darwin mailing list, I got it working using CFBundle. In fact, the code's *super* simple.

My question now, since I've generally avoided c macros like the plage, is how to make a macro along the lines of the following work:

Code:
#define FACTORY(cname) extern "C" ClassLoadable *cname_create(void){ return new cname; }

Such that in my code I could define a class as such:

Code:
class Foo : public ClassLoadable
{
    public:
        Foo( void );
        virtual ~Foo( void );
        // and so on
};

FACTORY(Foo);

What I want is for this to expand to:
Code:
extern "C" ClassLoadable *Foo_create( void ) { return new Foo; }

But what it actually expands to is:
Code:
extern "C" ClassLoadable cname_create( void ) { return new Foo; }

Can any macro wizards here help me out?
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #3
If this a valid approach? It seems to work, but it leaves me feeling a little iffy.
Code:
#define _create
#define FACTORY(cname) extern "C" ClassLoadable * cname##_create(void){ return new cname; }
#undef _create

Like I said, it works, but I'm a little uncertain. Any thoughts?
Quote this message in a reply
Moderator
Posts: 365
Joined: 2002.04
Post: #4
I couldn't say if that works without trying it, but the '##' concatenation operator is definitely what you want. Check out this page, for example.

Neil Carter
Nether - Mac games and comic art
Quote this message in a reply
Sage
Posts: 1,199
Joined: 2004.10
Post: #5
Excellent! I can now get rid of my spurious #define _create. THanks for the link, I googled quite a bit for C macro info, but didn't stumble across that *very* useful page.

Thanks,
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  I met a question again,about dlopen. sakiel 7 3,946 Aug 22, 2007 10:18 PM
Last Post: OneSadCookie
  Renaming an executable in Xcode ia3n_g 5 3,437 Sep 6, 2006 05:23 PM
Last Post: ia3n_g
  dlopen for loading plugins unknown 3 2,657 Apr 18, 2006 11:17 AM
Last Post: TomorrowPlusX