Equvilant of Windows Dllmain() in QNX

Hi, I am porting some DLLs from Windows to QNX. To dynamically load and
call the .so I use ‘dlopen()’ and ‘dlsym()’. But I need an entry point
to and an exit point from the .so, something equivalent to Windows DLL’s
‘DllMain()’. ( init() and fini() in Solaris )

Appreciate any advise.

Thanks,
-Beth

_init() and _fini().

“Beth” <cbeth@us.ibm.com> wrote in message
news:3CCD6BD6.7D7CB276@us.ibm.com

Hi, I am porting some DLLs from Windows to QNX. To dynamically load and
call the .so I use ‘dlopen()’ and ‘dlsym()’. But I need an entry point
to and an exit point from the .so, something equivalent to Windows DLL’s
‘DllMain()’. ( init() and fini() in Solaris )

Appreciate any advise.

Thanks,
-Beth
\

Thanks kc for your response.

Is that
void _init(viod) {} and
void _fini(void) {}

I have another question. If I only want to export certain functions of the
shared library, how
would I do that. Create a .map file? What’s the format of .map file?

Appreciate your help.

Regards,
-Beth Chen

kc wrote:

_init() and _fini().

“Beth” <> cbeth@us.ibm.com> > wrote in message
news:> 3CCD6BD6.7D7CB276@us.ibm.com> …
Hi, I am porting some DLLs from Windows to QNX. To dynamically load and
call the .so I use ‘dlopen()’ and ‘dlsym()’. But I need an entry point
to and an exit point from the .so, something equivalent to Windows DLL’s
‘DllMain()’. ( init() and fini() in Solaris )

Appreciate any advise.

Thanks,
-Beth
\

Actually _init and _fini are already used in the startup files. The
easiest way to get this behaviour is to use a static constructor/destructor
pair, eg

#include <stdio.h>

class InitFini {
public:
InitFini( ) { printf(“Init!\n”); }
~InitFini( ) { printf(“Fini!\n”); }
};

static InitFini initfini;

Thus the constructor will be executed when your dll is loaded, and
the destructor when it is unloaded.

I have another question. If I only want to export certain functions of the
shared library, how
would I do that. Create a .map file? What’s the format of .map file?

You need to use the version-script facility.

add to your link line

-Wl,–version-script=myscript

and in myscript

EXPORT {
global: exportFunctionOne;
exportFunctionTwo;
exportFunction*;

local: *;
};


cburgess@qnx.com

Usually, I will do something like the following.

static int _init() attribute ((constructor));
static int _fini() attribute ((destructor));
int _init() { printf(“init!\n”); }
int _fini() { printf(“fini!\n”); }

I like Colin’s approach, but I am not sure how it works. What
will happen if you also have some other classes similar to InitFini?
Will the system confuse which one to call?

Thanks
kc

“Colin Burgess” <cburgess@qnx.com> wrote in message
news:aakq05$ag6$1@nntp.qnx.com

Actually _init and _fini are already used in the startup files. The
easiest way to get this behaviour is to use a static
constructor/destructor
pair, eg

#include <stdio.h

class InitFini {
public:
InitFini( ) { printf(“Init!\n”); }
~InitFini( ) { printf(“Fini!\n”); }
};

static InitFini initfini;

Thus the constructor will be executed when your dll is loaded, and
the destructor when it is unloaded.

I have another question. If I only want to export certain functions of
the
shared library, how
would I do that. Create a .map file? What’s the format of .map file?

You need to use the version-script facility.

add to your link line

-Wl,–version-script=myscript

and in myscript

EXPORT {
global: exportFunctionOne;
exportFunctionTwo;
exportFunction*;

local: *;
};


cburgess@qnx.com

Colin, thanks for your help.

I can’t get your code to work with my C program. Would the following work the
same?

#include <dlfcn.h>

#pragma init (_init)
#pragma fini(_fini)

void init() {
printf(“init!\n”);
}
void fini(){
printf(“fini!\n”);
}

Also, I used the Wl, --version-script=myexport for the shared library.
I have a test program that links to the shared library. However, after I
compiled the test program,
if failed to run. The error message is: Could not find library
–version-script=myexport.

Am I missing something here?

Appreciate your help.

-Beth

Colin Burgess wrote:

Actually _init and _fini are already used in the startup files. The
easiest way to get this behaviour is to use a static constructor/destructor
pair, eg

#include <stdio.h

class InitFini {
public:
InitFini( ) { printf(“Init!\n”); }
~InitFini( ) { printf(“Fini!\n”); }
};

static InitFini initfini;

Thus the constructor will be executed when your dll is loaded, and
the destructor when it is unloaded.

I have another question. If I only want to export certain functions of the
shared library, how
would I do that. Create a .map file? What’s the format of .map file?

You need to use the version-script facility.

add to your link line

-Wl,–version-script=myscript

and in myscript

EXPORT {
global: exportFunctionOne;
exportFunctionTwo;
exportFunction*;

local: *;
};


cburgess@qnx.com

kc <kc@netnobound.com> wrote:

Usually, I will do something like the following.

static int _init() attribute ((constructor));
static int _fini() attribute ((destructor));
int _init() { printf(“init!\n”); }
int _fini() { printf(“fini!\n”); }

Nice one kc, I forgot about those attributes.

I like Colin’s approach, but I am not sure how it works. What
will happen if you also have some other classes similar to InitFini?
Will the system confuse which one to call?

It’s just a global object that is created/destroyed at load/unload.
You can call it whatever you like, and have as many as you like.


cburgess@qnx.com

Beth <id@address.com> wrote:

Colin, thanks for your help.

I can’t get your code to work with my C program. Would the following work the
same?

You should put the C++ stuff in another object file, or
see kc’s post for a solution in C, actually, here it is:

static int _init() attribute ((constructor));
static int _fini() attribute ((destructor));
int _init() { printf(“init!\n”); }
int _fini() { printf(“fini!\n”); }

Also, I used the Wl, --version-script=myexport for the shared library.
I have a test program that links to the shared library. However, after I
compiled the test program,
if failed to run. The error message is: Could not find library
–version-script=myexport.

Can you post the whole link line for your shared library?


cburgess@qnx.com

My link line looks like this:

qcc -V gcc_ntox86 -DNTO_X86 -Wl,-shared,-h -Wl,–version-script=myexport.qnx
obj1.o obj2.o -o …/lib/libfs.so

It ran fine and generate the libfs.so file.

I have a test program that uses this shared libary libfs.so. When I ran the test
program,
the error message is:
Could not find library --version-script=myexport.qnx

The myexport.qnx file looks like the following:
libfs.so
{
global:
func1;
func2;
local:
*;
};

Thanks,
-Beth


Colin Burgess wrote:

Beth <> id@address.com> > wrote:
Colin, thanks for your help.

I can’t get your code to work with my C program. Would the following work the
same?

You should put the C++ stuff in another object file, or
see kc’s post for a solution in C, actually, here it is:

static int _init() attribute ((constructor));
static int _fini() attribute ((destructor));
int _init() { printf(“init!\n”); }
int _fini() { printf(“fini!\n”); }

Also, I used the Wl, --version-script=myexport for the shared library.
I have a test program that links to the shared library. However, after I
compiled the test program,
if failed to run. The error message is: Could not find library
–version-script=myexport.

Can you post the whole link line for your shared library?


cburgess@qnx.com

“Colin Burgess” <cburgess@qnx.com> wrote in message
news:aan4cm$4io$2@nntp.qnx.com

kc <> kc@netnobound.com> > wrote:
Usually, I will do something like the following.

static int _init() attribute ((constructor));
static int _fini() attribute ((destructor));
int _init() { printf(“init!\n”); }
int _fini() { printf(“fini!\n”); }

Nice one kc, I forgot about those attributes.

I like Colin’s approach, but I am not sure how it works. What
will happen if you also have some other classes similar to InitFini?
Will the system confuse which one to call?

It’s just a global object that is created/destroyed at load/unload.
You can call it whatever you like, and have as many as you like.

I get it. Thanks a lot.

kc


cburgess@qnx.com

Beth <id@address.com> wrote:

My link line looks like this:

qcc -V gcc_ntox86 -DNTO_X86 -Wl,-shared,-h -Wl,–version-script=myexport.qnx
^^
obj1.o obj2.o -o …/lib/libfs.so

Ok, I see the problem.

Instead of -Wl,-shared,-h you should have -shared -Wl,-h,libfs.so

-h sets the DT_SONAME record in the shared library, which is noted when
you link against that shared lib. You were accidentally setting the SONAME
to --version-script=myexport.qnx, so the app looked for that when starting
up.

Also note that -shared should be passed directly to qcc, not via the
-Wl interface.

\

cburgess@qnx.com

It’s working now. Thanks to Colin and kc.

I have another question, how do I add a command to the common.mk at the end of the
creating the shared library.

Following is my common.mk file.

ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)

NAME=libfs

TOPDIR=…/…/…/…/…/…/…/…
INSTALL_ROOT_nto=$(TOPDIR)/fs
INSTALLDIR=/

EXCLUDE_OBJS = pthread.o

CCFLAGS += -nostdinc -DQNX -shared
LDFLAGS =-Wl,–version-script=$(PROJECT_ROOT)/export.qnx

include $(MKFILES_ROOT)/qtargets.mk

I need to run a commond towards the libfs.so for adding a signature. How do I do
that?

If this is not the right form to discuss, let me know which form I should post this
question to.

Thanks for your help.

-Beth



Colin Burgess wrote:

Beth <> id@address.com> > wrote:
My link line looks like this:

qcc -V gcc_ntox86 -DNTO_X86 -Wl,-shared,-h -Wl,–version-script=myexport.qnx
^^
obj1.o obj2.o -o …/lib/libfs.so

Ok, I see the problem.

Instead of -Wl,-shared,-h you should have -shared -Wl,-h,libfs.so

-h sets the DT_SONAME record in the shared library, which is noted when
you link against that shared lib. You were accidentally setting the SONAME
to --version-script=myexport.qnx, so the app looked for that when starting
up.

Also note that -shared should be passed directly to qcc, not via the
-Wl interface.


cburgess@qnx.com

I think there is a macro called POST_BUILD (and a PRE_BUILD)

Beth <id@address.com> wrote:

It’s working now. Thanks to Colin and kc.

I have another question, how do I add a command to the common.mk at the end of the
creating the shared library.

Following is my common.mk file.

ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)

NAME=libfs

TOPDIR=…/…/…/…/…/…/…/…
INSTALL_ROOT_nto=$(TOPDIR)/fs
INSTALLDIR=/

EXCLUDE_OBJS = pthread.o

CCFLAGS += -nostdinc -DQNX -shared
LDFLAGS =-Wl,–version-script=$(PROJECT_ROOT)/export.qnx

include $(MKFILES_ROOT)/qtargets.mk

I need to run a commond towards the libfs.so for adding a signature. How do I do
that?

If this is not the right form to discuss, let me know which form I should post this
question to.

Thanks for your help.

-Beth



Colin Burgess wrote:

Beth <> id@address.com> > wrote:
My link line looks like this:

qcc -V gcc_ntox86 -DNTO_X86 -Wl,-shared,-h -Wl,–version-script=myexport.qnx
^^
obj1.o obj2.o -o …/lib/libfs.so

Ok, I see the problem.

Instead of -Wl,-shared,-h you should have -shared -Wl,-h,libfs.so

-h sets the DT_SONAME record in the shared library, which is noted when
you link against that shared lib. You were accidentally setting the SONAME
to --version-script=myexport.qnx, so the app looked for that when starting
up.

Also note that -shared should be passed directly to qcc, not via the
-Wl interface.


cburgess@qnx.com


cburgess@qnx.com

Colin, thanks !

The POST_BUILD macro works great.

Very much appreciate your help.

-Beth


Colin Burgess wrote:

I think there is a macro called POST_BUILD (and a PRE_BUILD)

Beth <> id@address.com> > wrote:
It’s working now. Thanks to Colin and kc.

I have another question, how do I add a command to the common.mk at the end of the
creating the shared library.

Following is my common.mk file.

ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)

NAME=libfs

TOPDIR=…/…/…/…/…/…/…/…
INSTALL_ROOT_nto=$(TOPDIR)/fs
INSTALLDIR=/

EXCLUDE_OBJS = pthread.o

CCFLAGS += -nostdinc -DQNX -shared
LDFLAGS =-Wl,–version-script=$(PROJECT_ROOT)/export.qnx

include $(MKFILES_ROOT)/qtargets.mk

I need to run a commond towards the libfs.so for adding a signature. How do I do
that?

If this is not the right form to discuss, let me know which form I should post this
question to.

Thanks for your help.

-Beth

Colin Burgess wrote:

Beth <> id@address.com> > wrote:
My link line looks like this:

qcc -V gcc_ntox86 -DNTO_X86 -Wl,-shared,-h -Wl,–version-script=myexport.qnx
^^
obj1.o obj2.o -o …/lib/libfs.so

Ok, I see the problem.

Instead of -Wl,-shared,-h you should have -shared -Wl,-h,libfs.so

-h sets the DT_SONAME record in the shared library, which is noted when
you link against that shared lib. You were accidentally setting the SONAME
to --version-script=myexport.qnx, so the app looked for that when starting
up.

Also note that -shared should be passed directly to qcc, not via the
-Wl interface.


cburgess@qnx.com


cburgess@qnx.com

Hey Beth,

For some reasons, I could not see some of earlier posts on this topic.
Strange. Goolge doesnt seem to have this group’s archives Could you
forward them me? I just want to write down something for future
reference.

Thanks a lot.
kc

“Beth” <id@address.com> wrote in message
news:3CD2DAAC.7B3F1E3B@address.com

Colin, thanks !

The POST_BUILD macro works great.

Very much appreciate your help.

-Beth


Colin Burgess wrote:

I think there is a macro called POST_BUILD (and a PRE_BUILD)

Beth <> id@address.com> > wrote:
It’s working now. Thanks to Colin and kc.

I have another question, how do I add a command to the common.mk at
the end of the
creating the shared library.

Following is my common.mk file.

ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)

NAME=libfs

TOPDIR=…/…/…/…/…/…/…/…
INSTALL_ROOT_nto=$(TOPDIR)/fs
INSTALLDIR=/

EXCLUDE_OBJS = pthread.o

CCFLAGS += -nostdinc -DQNX -shared
LDFLAGS =-Wl,–version-script=$(PROJECT_ROOT)/export.qnx

include $(MKFILES_ROOT)/qtargets.mk

I need to run a commond towards the libfs.so for adding a signature.
How do I do
that?

If this is not the right form to discuss, let me know which form I
should post this
question to.

Thanks for your help.

-Beth

Colin Burgess wrote:

Beth <> id@address.com> > wrote:
My link line looks like this:

qcc -V
gcc_ntox86 -DNTO_X86 -Wl,-shared,-h -Wl,–version-script=myexport.qnx
^^
obj1.o obj2.o -o …/lib/libfs.so

Ok, I see the problem.

Instead of -Wl,-shared,-h you should have -shared -Wl,-h,libfs.so

-h sets the DT_SONAME record in the shared library, which is noted
when
you link against that shared lib. You were accidentally setting the
SONAME
to --version-script=myexport.qnx, so the app looked for that when
starting
up.

Also note that -shared should be passed directly to qcc, not via the
-Wl interface.


cburgess@qnx.com


cburgess@qnx.com

kc,
I didn’t know which post you were missing. I cut and pasted all of the response
regarding this subject and sent to your email address.

Thanks for your help.

-Beth

kc wrote:

Hey Beth,

For some reasons, I could not see some of earlier posts on this topic.
Strange. Goolge doesnt seem to have this group’s archives Could you
forward them me? I just want to write down something for future
reference.

Thanks a lot.
kc

“Beth” <> id@address.com> > wrote in message
news:> 3CD2DAAC.7B3F1E3B@address.com> …
Colin, thanks !

The POST_BUILD macro works great.

Very much appreciate your help.

-Beth


Colin Burgess wrote:

I think there is a macro called POST_BUILD (and a PRE_BUILD)

Beth <> id@address.com> > wrote:
It’s working now. Thanks to Colin and kc.

I have another question, how do I add a command to the common.mk at
the end of the
creating the shared library.

Following is my common.mk file.

ifndef QCONFIG
QCONFIG=qconfig.mk
endif
include $(QCONFIG)

NAME=libfs

TOPDIR=…/…/…/…/…/…/…/…
INSTALL_ROOT_nto=$(TOPDIR)/fs
INSTALLDIR=/

EXCLUDE_OBJS = pthread.o

CCFLAGS += -nostdinc -DQNX -shared
LDFLAGS =-Wl,–version-script=$(PROJECT_ROOT)/export.qnx

include $(MKFILES_ROOT)/qtargets.mk

I need to run a commond towards the libfs.so for adding a signature.
How do I do
that?

If this is not the right form to discuss, let me know which form I
should post this
question to.

Thanks for your help.

-Beth

Colin Burgess wrote:

Beth <> id@address.com> > wrote:
My link line looks like this:

qcc -V
gcc_ntox86 -DNTO_X86 -Wl,-shared,-h -Wl,–version-script=myexport.qnx
^^
obj1.o obj2.o -o …/lib/libfs.so

Ok, I see the problem.

Instead of -Wl,-shared,-h you should have -shared -Wl,-h,libfs.so

-h sets the DT_SONAME record in the shared library, which is noted
when
you link against that shared lib. You were accidentally setting the
SONAME
to --version-script=myexport.qnx, so the app looked for that when
starting
up.

Also note that -shared should be passed directly to qcc, not via the
-Wl interface.


cburgess@qnx.com


cburgess@qnx.com