Problem Using Torque as a Static Library
by Timothy May · in Torque Game Engine · 08/08/2005 (1:07 pm) · 6 replies
I am using TGE as library linked into an application written in TrollTech's Qt 3.3.3 environment. I have a project that contains the application's files (based on Qt classes etc) and I'm linking in a version of the TGE I have built as a static lib in a separate project.
FWIW, this meant I had to modify the Platform32/winWindow.cc by removing the main() and winMain() functions (main() is defined in the Qt app).
My problem is that I get assertions after the system starts up for missing console objects types. Basically, various console object types never made their way into the classLinkList. I've tracked this down to the crt0dat.c call to _initterm not finding these classes - I assume this means we have a compiler/linker problem. I some confirmation of this by defining a function in the first of the missing classes cc file and calling this function in the winWindow.cc run function - of course I could do this for all the ACR classes but that is a super ugly hack.
I can build and run the torque demo with no problems against the the starter.fps game. I'm also running against this game when I come up inside the Qt application.
Has anybody fought this battle before? I've been all over the Visual Studio linker settings but have struck out so far.
Regards,
Tim
FWIW, this meant I had to modify the Platform32/winWindow.cc by removing the main() and winMain() functions (main() is defined in the Qt app).
My problem is that I get assertions after the system starts up for missing console objects types. Basically, various console object types never made their way into the classLinkList. I've tracked this down to the crt0dat.c call to _initterm not finding these classes - I assume this means we have a compiler/linker problem. I some confirmation of this by defining a function in the first of the missing classes cc file and calling this function in the winWindow.cc run function - of course I could do this for all the ACR classes but that is a super ugly hack.
I can build and run the torque demo with no problems against the the starter.fps game. I'm also running against this game when I come up inside the Qt application.
Has anybody fought this battle before? I've been all over the Visual Studio linker settings but have struck out so far.
Regards,
Tim
About the author
#2
08/08/2005 (1:47 pm)
Just keep in mind that Torque is in no way designed or written to be used in this manner, so any issues or results you may (or may not) have are areas that most will not have explored...
#3
game\main.cc initLibraries() is called. Nothing this far into the startup is amiss. Thanks.
Sephen,
Yep - trust me to strap a rocket to my backside everytime. It's this or build our own monster from the ground up with the OGRE lib. However, I like TGE and its got a huge amount of really good stuff in it. I'll keep pounding for awhile to see if I can get this puppy to bark. Thanks.
Tim
08/08/2005 (1:57 pm)
Tony,game\main.cc initLibraries() is called. Nothing this far into the startup is amiss. Thanks.
Sephen,
Yep - trust me to strap a rocket to my backside everytime. It's this or build our own monster from the ground up with the OGRE lib. However, I like TGE and its got a huge amount of really good stuff in it. I'll keep pounding for awhile to see if I can get this puppy to bark. Thanks.
Tim
#4
Something else to try is to look at your Torque Library project in the Project Properties / C++ / Code Generation and make sure the runtime library is exactly the same as that of your QT project.
08/08/2005 (2:05 pm)
Oh well... was a suggestion.Something else to try is to look at your Torque Library project in the Project Properties / C++ / Code Generation and make sure the runtime library is exactly the same as that of your QT project.
#5
I have TGE working (more or less) inside Qt. By working I mean that the application comes up with the Qt window and TGE window (later I'll get the TGE rendering inside a Qt window) and the starter.fps to run. To solve the linking issues mentioned in prior posts I modified the IMPLEMENT_CO... macros as follows:
#define IMPLEMENT_CONOBJECT(className) \
bool Init##className = false; \
....
#define IMPLEMENT_CO_NETOBJECT_V1(className) \
bool Init##className = false; \
....
#define IMPLEMENT_CO_DATABLOCK_V1(className) \
bool Init##className = false; \
....
This means every console class file now has a variable like:
bool InitClassName = false;
In addition, I modified the winWindow.cc file run() function as follows:
extern bool LinkConsoleFunctions;
extern bool InitAudioProfile;
extern bool InitGuiFrameSetCtrl;
extern bool InitGuiControlListPopUp;
extern bool InitGuiConsoleEditCtrl;
extern bool InitGuiGraphCtrl;
extern bool InitGameTSCtrl;
extern bool InitGuiBitmapBorderCtrl;
extern bool InitGuiShapeNameHud;
extern bool InitGuiHealthBarHud;
extern bool InitGuiCrossHairHud;
extern bool InitGuiMessageVectorCtrl;
extern bool InitGuiChunkedBitmapCtrl;
extern bool InitGuiInputCtrl;
extern bool InitGuiFadeinBitmapCtrl;
extern bool InitScriptObject;
extern bool InitCameraData;
extern bool InitMissionMarker;
extern bool InitItemData;
extern bool InitSplashData;
extern bool InitProjectileData;
extern bool InitTSShapeConstructor;
extern bool InitPlayerData;
extern bool InitParticleEmitterNodeData;
extern bool InitMissionArea;
extern bool InitSky;
extern bool InitSun;
extern bool InitfxSunLight;
extern bool InitTSStatic;
extern bool InitAIPlayer;
S32 run(S32 argc, const char **argv)
{
// Hacks to ensure consolefunctions and console objects get linked in
LinkConsoleFunctions=true;
InitAudioProfile=true;
InitGuiFrameSetCtrl=true;
InitGuiControlListPopUp=true;
InitGuiConsoleEditCtrl=true;
InitGuiGraphCtrl=true;
InitGameTSCtrl=true;
InitGuiBitmapBorderCtrl=true;
InitGuiShapeNameHud=true;
InitGuiHealthBarHud=true;
InitGuiCrossHairHud=true;
InitGuiMessageVectorCtrl=true;
InitGuiChunkedBitmapCtrl=true;
InitGuiInputCtrl=true;
InitGuiFadeinBitmapCtrl=true;
InitScriptObject=true;
InitCameraData=true;
InitMissionMarker=true;
InitItemData=true;
InitSplashData=true;
InitProjectileData=true;
InitTSShapeConstructor=true;
InitPlayerData=true;
InitParticleEmitterNodeData=true;
InitMissionArea=true;
InitSky=true;
InitSun=true;
InitfxSunLight=true;
InitTSStatic=true;
InitAIPlayer=true;
createFontInit();
windowSize.set(0,0);
S32 ret = Game->main(argc, argv);
createFontShutdown();
return ret;
}
This gets all of the classes I need to get starter.fps to run. Clearly, there are more classes that should be referenced but that will be the next step. This is clearly an ugly hack; redemmed only by the fact that it works. If anyone comes up with a better technique please let me know.
Cheers,
Tim
08/08/2005 (6:14 pm)
All,I have TGE working (more or less) inside Qt. By working I mean that the application comes up with the Qt window and TGE window (later I'll get the TGE rendering inside a Qt window) and the starter.fps to run. To solve the linking issues mentioned in prior posts I modified the IMPLEMENT_CO... macros as follows:
#define IMPLEMENT_CONOBJECT(className) \
bool Init##className = false; \
....
#define IMPLEMENT_CO_NETOBJECT_V1(className) \
bool Init##className = false; \
....
#define IMPLEMENT_CO_DATABLOCK_V1(className) \
bool Init##className = false; \
....
This means every console class file now has a variable like:
bool InitClassName = false;
In addition, I modified the winWindow.cc file run() function as follows:
extern bool LinkConsoleFunctions;
extern bool InitAudioProfile;
extern bool InitGuiFrameSetCtrl;
extern bool InitGuiControlListPopUp;
extern bool InitGuiConsoleEditCtrl;
extern bool InitGuiGraphCtrl;
extern bool InitGameTSCtrl;
extern bool InitGuiBitmapBorderCtrl;
extern bool InitGuiShapeNameHud;
extern bool InitGuiHealthBarHud;
extern bool InitGuiCrossHairHud;
extern bool InitGuiMessageVectorCtrl;
extern bool InitGuiChunkedBitmapCtrl;
extern bool InitGuiInputCtrl;
extern bool InitGuiFadeinBitmapCtrl;
extern bool InitScriptObject;
extern bool InitCameraData;
extern bool InitMissionMarker;
extern bool InitItemData;
extern bool InitSplashData;
extern bool InitProjectileData;
extern bool InitTSShapeConstructor;
extern bool InitPlayerData;
extern bool InitParticleEmitterNodeData;
extern bool InitMissionArea;
extern bool InitSky;
extern bool InitSun;
extern bool InitfxSunLight;
extern bool InitTSStatic;
extern bool InitAIPlayer;
S32 run(S32 argc, const char **argv)
{
// Hacks to ensure consolefunctions and console objects get linked in
LinkConsoleFunctions=true;
InitAudioProfile=true;
InitGuiFrameSetCtrl=true;
InitGuiControlListPopUp=true;
InitGuiConsoleEditCtrl=true;
InitGuiGraphCtrl=true;
InitGameTSCtrl=true;
InitGuiBitmapBorderCtrl=true;
InitGuiShapeNameHud=true;
InitGuiHealthBarHud=true;
InitGuiCrossHairHud=true;
InitGuiMessageVectorCtrl=true;
InitGuiChunkedBitmapCtrl=true;
InitGuiInputCtrl=true;
InitGuiFadeinBitmapCtrl=true;
InitScriptObject=true;
InitCameraData=true;
InitMissionMarker=true;
InitItemData=true;
InitSplashData=true;
InitProjectileData=true;
InitTSShapeConstructor=true;
InitPlayerData=true;
InitParticleEmitterNodeData=true;
InitMissionArea=true;
InitSky=true;
InitSun=true;
InitfxSunLight=true;
InitTSStatic=true;
InitAIPlayer=true;
createFontInit();
windowSize.set(0,0);
S32 ret = Game->main(argc, argv);
createFontShutdown();
return ret;
}
This gets all of the classes I need to get starter.fps to run. Clearly, there are more classes that should be referenced but that will be the next step. This is clearly an ugly hack; redemmed only by the fact that it works. If anyone comes up with a better technique please let me know.
Cheers,
Tim
#6
08/08/2005 (7:01 pm)
Clever hack. Congratulations on sucking it up and solving the problem - most people just whine about it and move on. ;)
Torque 3D Owner Tony Richards