XCode 2.2 has broken my app's classloading
XCode 2.2 has broken my app's classloading
- Subject: XCode 2.2 has broken my app's classloading
- From: Shamyl Zakariya <email@hidden>
- Date: Fri, 11 Nov 2005 12:11:59 -0500
All
This is my first message to this list -- thus far I've had no
particular troubles with Xcode.
Anyway, this morning I upgraded to Xcode 2.2, and found that from
within Xcode I can no longer run my game. Oddly, I *can* run it from
the finder. Which is to say, the executable works fine, but some
aspect of the Xcode app-running environment breaks my app.
Now, onto the details:
My game is written primarily in C++, running from a Cocoa shell which
gives me input, sound, and OpenGL and whatnot. The other 98% is C++.
Since C++ doesn't have formal classloading capacity, I sort of hacked
up a variant using CFBundleGetFunctionPointerForName() where any
classes which are intended to be "classloadable" have a factory
method macro which exposes a constructor, which can be aliased at
runtime by name.
The macro looks something like:
FACTORY(Forestation);
Where "Forestation" is the name of the class, it could be anything,
like "SkyBox", "Terrain", etc.
The macro is defined as such:
#define FACTORY(cname) extern "C" DOMInitializable * cname ## _create
(void){ return new cname; }
Which would expand to:
extern "C" DOMInitializable *Forestation_create(void) { return new
Forestation; }
Now, onto the meat of the issue: the Factory class has a load
function which takes a classname:
DOMInitializableFactoryFunction *Factory::load( std::string classname )
{
/*
If we've already aliased the factory for this class, return it.
Else, let CFBundle look it up, then store it in the map.
*/
if ( _factories.find( classname ) != _factories.end() )
{
return _factories[ classname ];
}
// debugging, making certain my bundle is right -- it should be
the .app bundle
{
CFURLRef url = CFBundleCopyBundleURL(CFBundleGetMainBundle());
CFStringRef path = CFURLCopyFileSystemPath( url,
kCFURLPOSIXPathStyle );
NSString *str = (NSString *) path;
NSLog( @"My bundle path is: %@", str );
}
std::string factoryName = classname + "_create";
void *ptr = CFBundleGetFunctionPointerForName( CFBundleGetMainBundle(),
(CFStringRef)
[NSString stringWithCString: factoryName.c_str()]);
if ( !ptr )
{
// this is where it's bailing under Xcode 2.2 -- worked before!
NSLog( @"Couldn't alias function pointer for %s", factoryName.c_str
() );
return NULL;
}
DOMInitializableFactoryFunction *fn = (DOMInitializable *(*)(void))
ptr;
_factories[ classname ] = fn;
return fn;
}
When run from the finder, this works fine.
CFBundleGetFunctionPointerForName returns the factory function and it
invokes properly. However, when run from Xcode 2.2... it bails on the
if ( !ptr ) line.
This ran fine yesterday under Xcode 2.1, and under 2.0 as well.
My initial assumption was that Xcode is running the app via some
wrapper app shell, and I was getting an incorrect bundle, so I added
the code which NSLogs the bundle path. But to my chagrin, it prints
the expected path.
Here's the output from Xcode:
2005-11-11 12:05:28.717 WorldEngine[2243] My bundle path is: /Users/
zakariya/Projects/WorldEngine/build/Deployment/WorldEngine.app
2005-11-11 12:05:28.717 WorldEngine[2243] Couldn't alias function
pointer for SkyDome_create
Whereas the output on the console, running from the Finder -- where
it works fine -- is:
2005-11-11 12:08:06.776 WorldEngine[2252] My bundle path is: /Users/
zakariya/Projects/WorldEngine/build/Deployment/WorldEngine.app
So, can anybody give me some pointer as to what's going on? This is
unbearable!
shamyl zakariya
"all humans are vermin, in the eyes of morbo"
-- morbo
_______________________________________________
Do not post admin requests to the list. They will be ignored.
Xcode-users mailing list (email@hidden)
Help/Unsubscribe/Update your Subscription:
This email sent to email@hidden