Hi,

We are using a multithreaded application which has a few dynamic
shared objects associated with it. We are running it on Linux
platform. Few of the classes and code part is common among main
executable and other DSOs. The DSOs have been linked using linker
option -Bsymbolic and so are able to keep their seperate objects for
common classes.


The issue we are having is we want to keep a true singleton of the
common class without disturbing current linker option. For this
purpose, we are setting an environment variable with address of object
initialised first of all, so that once initialised same object is used
among all DSOs.


Please see below source code of sample application, which models my
problem.


// ************* LIB.H *************


#include "string.h"
#include
#include
#include


class Common
{
private:
char name[20];
static Common *_theRegistry;
Common()
{
printf ("Constructor Invoked!!\n");
}
public:
static Common *InitInstance();
static Common *GetInstance();
char* getName();



};


// ************* LIB.CPP *************

#include "lib.h"
//#include


const char *kENVKEY = "MYKEY";
Common *Common::_theRegistry = NULL;
char * Common::getName(){
return name;



}


Common *Common::InitInstance()
{
long longEnvVal;
char *EnvVal = getenv(kENVKEY) ;

printf("getenv Val (%s)\n",EnvVal);


if(EnvVal == NULL || strtol(EnvVal, NULL, 10) == -1 )
{
if(_theRegistry == NULL)
{
_theRegistry = new Common;


char strKey[9];
sprintf(strKey,"%0x",_theRegistry);
char *dupenv = strdup (strKey);
if( -1 == setenv(kENVKEY,strKey,0) )
{
fprintf(stderr,"Error in setenv
call!!!
\n");
exit(1);
}
}
printf("Object created (at %0x)\n ", _theRegistry);
}
else
{
longEnvVal = strtol(EnvVal, NULL, 16);
_theRegistry = (Common *)longEnvVal;
printf("Object found at: (%0x)\n", _theRegistry);
}


return _theRegistry;



}


Common *Common::GetInstance()
{
if ( _theRegistry == NULL )
return InitInstance();
else
return _theRegistry;


}


// ************* SOFILE.CPP *************

#include
#include "lib.h"


Common* pSinglton=Common::GetInstance();
extern "C" {
void funBeforeDlopen()
{
printf("Function fron library invoke before Dlopen
call
\n");
}



}


// ************* MAIN.CPP *************

#include
#include
#include
#include "lib.h"


Common* pSinglton=Common::GetInstance();
void funMainFile(void);


int main()
{
void *handle;
char *error;
void(*pfun)();
printf("Blah Blah Blah of Main() now!\n");
return 0;



}


And here are my g++ command

g++ -fPIC -g -c lib.cpp
g++ -fPIC -g -c main.cpp
g++ -fPIC -g -c sofile.cpp


g++ -shared -Wl,-soname,libsofile.so -o libsofile.so sofile.o lib.o -
lc -Wl,-rpath,. -Wl,-Bsymbolic
g++ -g -o main.exe lib.o main.o libsofile.so -L. -lsofile -Wl,-rpath,.
-ldl


The output of the program is as follows


=====================
getenv Val ((null))
Constructor Invoked!!
Object created (at 8d4a008)
getenv Val ((null))
Constructor Invoked!!
Object created (at 8d4a0f0)
Blah Blah Blah of Main() now!
=====================


Please help me undertsand why I am not able to invoke environment
variable set by first invocation of constructor of singleton. Also
please let me know what is the best way to solve such kind of
problem.

Any help in this regard willl be greatly appreciated.


Thanks and Regards
Bhawna