Operating System - HP-UX
1751782 Members
4650 Online
108781 Solutions
New Discussion юеВ

Re: C++ shared library loading not calling constructor for global and static const members not being set

 
Steven J. Saunders
Occasional Advisor

C++ shared library loading not calling constructor for global and static const members not being set

We are trying to port some code that works fine on WIN32, AIX, Solaris, and Linux to HP-UX. This shared library loads fine but we have noticed that the one global variable for a class is not getting it's constructor called. We tried working around this with +init/+fini and with +I linker options with problems.

We changed the code to have the global initialized with the first call into the main entry point/C function in the shared object. Then we noticed a related problem, all our static const members that we initialized with a value are not getting initialized, almost as if these const members are not getting setup either when the shared object loads.

We are using the /usr/bin/ld linker, the commercial ansic and aCC compilers on HP-UX PA-RISC 11i v1 that is brand new with the GOLDBUNDLE 11i from June 04 and with lots of new patches.

What are we doing wrong. We tried building the shared object with the linker directly and with the ansic complier and then with the aCC compiler to call the linker. No difference. We did this because of different info in different locations in documentation about how to do it.

Help!
6 REPLIES 6
ranganath ramachandra
Esteemed Contributor

Re: C++ shared library loading not calling constructor for global and static const members not being set

the correct way to do this is to use only aCC for compiling AND linking. but you say you have tried it already.

is it possible to reduce the problem to a minimal piece of code and compile/link line ? for example, this script shows you what works and what does not:
-----
[12:39:35] $ cat con.tst
cat > 1.h << \!
#include
class A {
private:
int a;
public:
A (int i) { a=i; printf("constructor called with %d\n", i); }
~A () { printf("destructor called for %d\n", a); }
};
!
cat > 1.c << \!
#include "1.h"
static A a(5);
static A *b;
extern "C" void function () { puts("function called"); }
#ifdef USE_INITFINI
extern "C" void init () { a=A(5); }
extern "C" void fini () { (&a)->~A(); }
#endif
!
cat > 2.c << \!
#include
#include
int main () {
void *dl;
void (*func)();
puts("before dlopen");
dl = dlopen("lib1.sl", RTLD_LAZY);
puts("after dlopen");
if (dl == NULL)
return 1;
func = (void(*)())dlsym (dl, "function");
if (func != NULL) {
(*func)();
}
puts("before dlclose");
dlclose(dl);
puts("after dlclose");
return 0;
}
!
aCC 1.c -b +z -o lib1.sl
aCC 2.c
echo
echo ---- compiled and linked with aCC ----
./a.out

aCC +z -c 1.c
ld -b 1.o -o lib1.sl
echo
echo ---- linked plain with ld ----
./a.out

aCC +z -DUSE_INITFINI -c 1.c
ld -b 1.o +init init +fini fini -o lib1.sl
echo
echo ---- linked with ld, with init and fini ----
./a.out
echo
----

in my environment:
----

[12:39:35] $ ksh con.tst

---- compiled and linked with aCC ----
before dlopen
constructor called with 5
after dlopen
function called
before dlclose
destructor called for 5
after dlclose

---- linked plain with ld ----
before dlopen
after dlopen
function called
before dlclose
after dlclose

---- linked with ld, with init and fini ----
before dlopen
constructor called with 5
destructor called for 5
after dlopen
function called
before dlclose
destructor called for 5
after dlclose

[12:39:39] $ aCC -V
aCC: HP ANSI C++ B3910B A.03.55
[12:40:57] $ /usr/sbin/swlist | grep -i linker
PHSS_19866 1.0 ld(1) and linker tools cumulative patch
PHSS_28433 1.0 linker startup code / SLLIC ELF support
PHSS_30969 1.0 ld(1) and linker tools cumulative patch
----
 
--
ranga
[i work for hpe]

Accept or Kudo

Steven J. Saunders
Occasional Advisor

Re: C++ shared library loading not calling constructor for global and static const members not being set

Thanks, tried the simple program approach. Now the problem seems to be that I am linking the EXE with ld. If I link it by using cc I recreate the problem in my simple program.

Can I link C libraries and exes with aCC even though they are straight ansi C?
Steven J. Saunders
Occasional Advisor

Re: C++ shared library loading not calling constructor for global and static const members not being set

One additional problem. When trying to link the EXE with aCC it is not finding my shared objects but the -L pathname -lsharedobj is in there.
It says:
/usr/ccs/bin/ld: Can't find library: "ibase"

The -L../../hpxbin where the shared obj is located is in there and the -libase is after it.

Is there a problem with aCC calling the linker to make an EXE with resolving the locations of the shared objects?
Stephen Keane
Honored Contributor

Re: C++ shared library loading not calling constructor for global and static const members not being set

You are going to run into problems with name magling if you compile with one c++ compiler and link with another. Do an nm on the library and the binary you ate trying to link it to and you see the name decorations are probably different. You can either (a) compile and link with the same c++ compiler , or (b) in the header files surround the function declarations with extern "C" { func_defs } so that they don't get name mangled.
Steven J. Saunders
Occasional Advisor

Re: C++ shared library loading not calling constructor for global and static const members not being set

I have this resolved now. Thanks for all your help.

The problem I was having with getting the compiler to call the linker and resolve linked in libraries uisng the -L path option was because of a TYPO, +AA instead of -AA.

Also the problem is that the C shared object that loads other shared objects that can be C or C++ has to be linked with using aCC to call the linker for it to properly call the global's constructors and so forth.

Thanks.
Steven J. Saunders
Occasional Advisor

Re: C++ shared library loading not calling constructor for global and static const members not being set

See message above.