GIDForums  

Go Back   GIDForums > Computer Programming Forums > C++ Forum
User Name
Password
Register FAQ Members List Calendar Search Today's Posts Mark Forums Read

 
 
Thread Tools Search this Thread Rate Thread
  #1  
Old 01-Nov-2008, 06:59
PC Nerd PC Nerd is offline
New Member
 
Join Date: Feb 2007
Posts: 13
PC Nerd is on a distinguished road

Loading shared libraries - dlopen unknown reference - dlfcn not working?


Hi,

Just learnign on working with dll's and shared libraries... I've successfully got it complied into the dll ( im working on windows XP at the moment wiht MinGW)... However i cannot seem to load that dll. I'm trying to load it dynamically through code and not at compile time.....

by default my system didn't have dlfcn in its libraries... so i downloaded it from http://code.google.com/p/dlfcn-win32/downloads/list - both the non source code ones havent worked. I've coppied the dll's and .a files etc into the respective directories at c:\MinGW where MinGW is installed. I know for a fact that its my path etc. Unfortunately neither of the two downloads work.

At the moment I havent been able to compile the source from scratch because it uses Make.... and im following the trail of "<whatever> is not a recognised command" output etc....... so it might take a while for me to use that option.

My code and output from the compile is below...... but if anyone can suggest a method by which I can get the dlfcn library installed? - thanks




heres my code:

CPP / C++ / C Code:
#include <stdlib.h>
#include <stdio.h>
#include <dlfcn.h>

#include "sharedlib.h"

typedef IUnknown* create_t();
typedef void destroy_t(IUnknown*);

int main(void)
{
  // Load the library
  void* testlib = dlopen("tree.dll", RTLD_LAZY);

  if (!testlib) {
    printf("Cannot load library - %s\n", dlerror());
    return EXIT_FAILURE;
  }

  create_t* create_object = (create_t*)dlsym(testlib, "create");
  destroy_t* destroy_object = (destroy_t*)dlsym(testlib, "destroy");

  if (!create_object || !destroy_object) {
    printf("Cannot load symbols - %s\n", dlerror());
    return EXIT_FAILURE;
  }

  // Create the object
  IUnknown *iunk = create_object();

  // Print something to the screen
  iunk->QueryInterface("Simple Test of QueryInterface");

  // Destroy the object
  destroy_object(iunk);

  // Close the library
  dlclose(testlib);
  return EXIT_SUCCESS;
}



I'm musing Scons as the build system, but its the same when i manually go "g++ main.cpp -ldl" it doesnt work either...


Code:
scons: done reading SConscript files. scons: Building targets ... g++ -o tree.o -c tree.cc g++ -shared -o tree.dll tree.o -Wl,--out-implib,libtree.a -Wl,--output-def,tree. def Creating library file: libtree.a g++ -o main.o -c main.cpp main.cpp:40:2: warning: no newline at end of file g++ -o run.exe main.o main.o:main.cpp:(.text+0x3a): undefined reference to `dlopen(char const*, int)' main.o:main.cpp:(.text+0x48): undefined reference to `dlerror()' main.o:main.cpp:(.text+0x77): undefined reference to `dlsym(void*, char const*)' main.o:main.cpp:(.text+0x8d): undefined reference to `dlsym(void*, char const*)' main.o:main.cpp:(.text+0xa1): undefined reference to `dlerror()' main.o:main.cpp:(.text+0xef): undefined reference to `dlclose(void*)' collect2: ld returned 1 exit status scons: *** [run.exe] Error 1 scons: building terminated because of errors.
  #2  
Old 01-Nov-2008, 09:05
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,217
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: loading shared libraries - dlopen unknown reference - dlfcn not working?


Quote:
Originally Posted by PC Nerd
...I've coppied the dll's and .a files etc into the respective directories at c:\MinGW where MinGW is installed
Does this mean that you ave copied libdl.a into MinGW\lib?

Try the following:
  1. Download dlfcn-win32-static-r8.tar.bz2. Untar it. Copy libdl.a to your mingw lib directory and copy dlfcn.h to your mingw include directory.
  2. Navigateto MinGW\lib and execute the following from a command line:

    Code:
    nm -s libdl.a
You should see something like
Code:
Archive index: _dlopen in dlfcn.o _dlclose in dlfcn.o _dlsym in dlfcn.o _dlerror in dlfcn.o dlfcn.o: 00000000 b .bss 00000000 d .data 00000000 r .rdata 00000000 t .text U _CloseHandle@4 U _FormatMessageA@28 U _FreeLibrary@4 U _GetLastError@0 U _GetModuleHandleA@4 U _GetProcAddress@8 U _LoadLibraryExA@12 U _SetErrorMode@4 00000260 T _dlclose 000003c0 T _dlerror 00010010 b _dlerror_was_last_call 00000140 T _dlopen 00000310 T _dlsym 00000010 b _error_buffer 00000000 b _first_object U _free U _malloc 00000000 t _save_err_str U _sprintf

Quote:
Originally Posted by PC Nerd
. I know for a fact that its my path etc.
Navigate back to the directory where you have the source code.
What happens when you execute the following from a command line?
Quote:
g++ -v main.cpp -ldl


The "-v" tells g++ to show you the paths where it is looking for stuff.

If it looks in the directory where you have libdl.a but still gives the error messages, that means that the library against which the downloaded files were compiled are not compatible with your installation, so you will have to download the source for dlfcn and compile it.

Regards,

Dave

Footnote: Are you using MinGW "barefoot" or are you using dev-cpp?
  #3  
Old 01-Nov-2008, 09:22
PC Nerd PC Nerd is offline
New Member
 
Join Date: Feb 2007
Posts: 13
PC Nerd is on a distinguished road

Re: loading shared libraries - dlopen unknown reference - dlfcn not working?


Thanks for the fast reply....

I did as you said ( actually jsut used the one i downloaded earlier which is the same one...)...

the output of the first command is the same...... and g++ -v ,ain.cpp -ldl spits out errors.... and the last few of them are the dlopen errors etc.

MinGW "barefoot" ??? I simply installed it. Im not using it with an IDE or anything...... most of my code edited in either notepad notepad++.

As I think i mentioned.. im using SCons as the build system instead of make...... so if theres anythign i can change there what would that be?

Thanks again.

P.S. - if I provide the versions of MinGW I installed is it possible to find this precompiled for that version?
Thanks
  #4  
Old 01-Nov-2008, 10:48
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,217
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: loading shared libraries - dlopen unknown reference - dlfcn not working?


Quote:
Originally Posted by PC Nerd
"barefoot"
Yes, I meant to ask whether you are using an IDE or just running from a command line. If you have installed mingw so that you can run from a command line, that's much easier for me to direct by "remote control."

Quote:
Originally Posted by PC Nerd
...is it possible to find this precompiled for that version?
Why not build it so there won't be any question that it is for your version?


Let's try this:
If you haven't done it already, download the source tarball: dlfcn-win32-r8.tar.bz2 and untar it

cd into the dlfcn-win32-r8 directory.

Open your text editor and paste the following
Code:
# Created by davekw7x # Change the PREFIX line to the path of your MinGW directory # This directory will have subdirectories lib and include PREFIX=C:\Dev-CPP libdir=$(PREFIX)\lib incdir=$(PREFIX)\include CC=gcc BUILD_SHARED=no BUILD_STATIC=yes BUILD_MSVC= DO_STRIP=yes


If your installation is at C:\MinGW, then change the prefix line to
Code:
PREFIX=C:\MinGW


Save the file as "config.mak"


Now, enter the following from a command line:

Code:
make clean make

Here's what I see after the "make" command:
Code:
gcc -o dlfcn.o -c dlfcn.c -O3 -fomit-frame-pointer ar cru libdl.a dlfcn.o ranlib libdl.a
If it builds libdl.a correctly then
Code:
make testdll.dll

Here's what I see
Code:
gcc -shared -o testdll.dll testdll.c

Next, enter
Code:
make test.exe

I see
Code:
gcc -o test.exe test.c -L. -ldl

If everything has gone OK up to here, you now have "test.exe" in that directory.

Finally
Code:
test

I see
Code:
Opened library globally: 10000000 Got global handle: 00400000 Got symbol from library handle: 100011D0 Hello, world! Got symbol from global handle: 100011D0 Hello, world! Closed library. Opened library locally: 10000000 Got symbol from library handle: 100011D0 Hello, world! Could not get symbol from global handle: "function": The handle is invalid. Closed library. Closed global handle.

Not that that last message (Could not get symbol from global handle...) is expected.

If it works, then make sure there aren't any other versions of libdl.a and dlfcn.h in your mingw directory tree. Then you can copy libdl.a to your mingw lib directory and copy dlfcn.h to the mingw include directory, or you can enter the following
Code:
make install

Regards,

Dave

Footnote: I recommend you go through the way to make test.exe that I showed, using libdl.a.

If you want to make libdll.dll instead of (or in addition to) libdll.a, then in config.mak, change "BUILD_STATIC=yes" to "BUILD_STATIC=no" and change "BUILD_SHARED=no" to "BUILD_SHARED=yes"

Then
Code:
make clean make make install

Note that I have tested libdl.a created in the first part, but I have not tested libdll.dll.
  #5  
Old 01-Nov-2008, 15:45
PC Nerd PC Nerd is offline
New Member
 
Join Date: Feb 2007
Posts: 13
PC Nerd is on a distinguished road

Re: loading shared libraries - dlopen unknown reference - dlfcn not working?


ok.....

Firstly - I had no idea about making the config.mak ( I've never used make otehr than a few builds on ubuntu)... so that got a long way..


1) I edited the PREFIX value to C:\MinGW

2)
C:\dlfcn>make clean
rm -f dlfcn.o libdl.dll libdl.a libdl.def libdl.dll.a libdl.lib libdl.exp test.e
xe testdll.dll
process_begin: CreateProcess((null), rm -f dlfcn.o libdl.dll libdl.a libdl.def l
ibdl.dll.a libdl.lib libdl.exp test.exe testdll.dll, ...) failed.
make (e=2): The system cannot find the file specified.
make: *** [clean] Error 2

3) make worked: but didnt the second time I went through ( I had to wipe the directory so i assume it looked for files that were there or something?)

...... but i continued with the rest of the commands

4) make testdll.dll worked with the same output

5) make test.exe did work - but did not run:
C:\dlfcn>test
Opened library globally: 64A80000
Got global handle: 00400000
Got symbol from library handle: 64A81180
Hello, world!
Got symbol from global handle: 64A81180
Hello, world!
---- then "test.exe has stopped responding and needs to close" windows dialog box ( god i hate those!!! lol)

6) make install because it says "A file or direct or C:\MinGW\Lib already exists"... so i assume it cant "append" as opposed to "write" to that directory? - ill i just copied across.

7) - I copied across the libdl.a file... and went to my project:
g++ main.cpp -ldl
says it cannot find ldl
however when i run that command again AFTER running g++ main.cpp then it works:

anyway - neither the with or without "-ldl" commands work - both still telling me that dlopen is a n undefined reference.





Thanks for your help.....
  #6  
Old 02-Nov-2008, 09:37
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,217
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: loading shared libraries - dlopen unknown reference - dlfcn not working?


Quote:
Originally Posted by PC Nerd
Firstly - I had no idea about making the config.mak
If you have a bash shell on your windows machine you can execute "./configure" and it creates a config.mak. I created config.mak for you in the hopes that you wouldn't have to change anything else to get the test program to compile

Quote:
Originally Posted by PC Nerd
C:\dlfcn>make clean
rm -f dlfcn.o libdl.dll libdl.a libdl.def libdl.dll.a libdl.lib libdl.exp test.e
xe testdll.dll
process_begin: CreateProcess((null), rm -f dlfcn.o libdl.dll libdl.a libdl.def l
ibdl.dll.a libdl.lib libdl.exp test.exe testdll.dll, ...) failed.
OK, I guess you don't have "rm.exe" I use cygwin/GNU port of the most useful command line tools on my Windows platform, not MinGW.
Quote:
Originally Posted by PC Nerd
3) make worked: but didnt the second time I went through ( I had to wipe the directory so i assume it looked for files that were there or something?)

Please follow these steps exactly:

OK, let's start all over again. I'll go step-by-step. The following is on a Windows XP machine.
Here's the new drill:
  1. Create a new directory, say C:\dlfcn
  2. Copy the file dlfcn-win32-r8.tar.bz2 into that directory and untar it
  3. cd into C:\dlfcn\dlfcn-win32-r8
  4. Delete the Makefile (or rename it to something like "Makefile_original"
  5. Open your text editor and paste the following into its edit window

    Code:
    # # dlfcn-win32 Makefile for MinGW # from davekw7x # # Assuming that H:\Mingw\bin is on your %path%, invoke # this by executing the following from a command line: # # del *.a # del *.o # del *.exe # del *.dll # # mingw32-make # # # PREFIX = H:\MinGW BINDIR = $(PREFIX)\bin LIBDIR = $(PREFIX)\lib INCDIR = $(PREFIX)\include CC = $(BINDIR)\gcc AR = $(BINDIR)\ar RANLIB = $(BINDIR)\ranlib all: libdl.a testdll.dll test1.exe dlfcn.o: $(CC) -o dlfcn.o -c dlfcn.c -O3 -fomit-frame-pointer libdl.a: dlfcn.o $(AR) cru libdl.a dlfcn.o $(RANLIB) libdl.a test1.exe: test.c $(TARGETS) $(CC) -o test1.exe test.c -L. -ldl testdll.dll: $(CC) -shared -o testdll.dll testdll.c

    (Don't retype it; past it from here)

  6. Change the PREFIX value to your MinGW installation directory (C:\MinGW)

  7. Execute the following from the command line
    Code:
    mingw32-make
  8. Here's what I see
    Code:
    C:\dlfcn\dlfcn-win32-r8>mingw32-make H:\MinGW\bin\gcc -o dlfcn.o -c dlfcn.c -O3 -fomit-frame-pointer H:\MinGW\bin\ar cru libdl.a dlfcn.o H:\MinGW\bin\ranlib libdl.a H:\MinGW\bin\gcc -shared -o testdll.dll testdll.c H:\MinGW\bin\gcc -o test1.exe test.c -L. -ldl
  9. Now when I do a dir command, and I see that there are files named "dlfnc.o", "libdl.a", "test1.exe" and "test1.dll"
  10. I execute test1.exe and I see:

    Code:
    C:\dlfcn\dlfcn-win32-r8>test1 Opened library globally: 10000000 Got global handle: 00400000 Got symbol from library handle: 100011D0 Hello, world! Got symbol from global handle: 100011D0 Hello, world! Closed library. Opened library locally: 10000000 Got symbol from library handle: 100011D0 Hello, world! Could not get symbol from global handle: "function": The handle is invalid. Closed library. Closed global handle.

If you see anything else at any of these steps, show me exactly what your system is telling you.

Regards,

Dave

Footnote: If you do get to the end and test1 executes, then do the following
Code:
move libdl.a C:\MinGW\lib move dlfcn.h C:\MinGW\include C:\Mingw\bin\gcc test.c -ldl -otest2.exe
When I did this (Using my MinGW installation directory), I didn't get any messages of any kind from the compiler.

Then I executed test2 and I saw
Code:
Opened library globally: 10000000 Got global handle: 00400000 Got symbol from library handle: 100011D0 Hello, world! Got symbol from global handle: 100011D0 Hello, world! Closed library. Opened library locally: 10000000 Got symbol from library handle: 100011D0 Hello, world! Could not get symbol from global handle: "function": The handle is invalid. Closed library. Closed global handle.

Now, if this works, please tell me, and I may be able to tell you how to get it to work with your C++ program.
  #7  
Old 02-Nov-2008, 11:19
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,217
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: loading shared libraries - dlopen unknown reference - dlfcn not working?


Quote:
Originally Posted by davekw7x
...Now, if this works...
I know that there was a lot of verbiage, so I would like to recap:

There are various versions of the dlfcn stuff floating around. Some compiler distributions have some version of libdl.a already included. I just wanted to make absolutely certain that you can compile the C test program from current dlfcn source and get correct (and consistent) results with your compiler.

If you get correct output from the test.c supplied with the dlfcn stuff, there is a very minor change that you will need to make to get it to be usable with C++ programs. (At least it works for me.)

Regards,

Dave
  #8  
Old 03-Nov-2008, 10:10
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,217
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: loading shared libraries - dlopen unknown reference - dlfcn not working?


Quote:
Originally Posted by davekw7x
...change that you will need to make to get it to be usable with C++ programs...

Once you can are absolutely sure that your results with C programs using libdl.a are correct, then here's what you need to do to make libdl.a usable with C++ programs:

You will not recompile libdl.a
It works. Leave it alone; leave it where it is (in the MinGW\lib directory)

Make the following changes to dlfcn.h:

Find the #ifndef statement
CPP / C++ / C Code:
#ifndef DLFCN_H
#define DLFCN_H

Add three lines following these so that you have:
CPP / C++ / C Code:
#ifndef DLFCN_H
#define DLFCN_H
#ifdef __cplusplus
extern "C" {
#endif

Then at the bottom of the file:
CPP / C++ / C Code:
#endif /* DLFCN_H */

Add three lines before this, so that now you have:

CPP / C++ / C Code:
#ifdef __cplusplus
}
#endif
#endif /* DLFCN_H */

Make sure that this replaces dlfcn.h in your Mingw\include directory and that you don't have any other dlfcn.h files sprinkled around the landscape.

Now in any C program that uses libdl.a, you include this file. The program can be linked with libdl.a by putting "-ldl" on the command line.

In any C++ program that uses libdl.a, you include this file. The program can be linked with libdl.a by putting "-ldl" on the command line.

That's all.

Regards,

Dave

Footnote: The identifier __cplusplus works with GNU compilers and is defined if you use g++ but it is not defined if you use gcc.

That means that it the extra lines have no effect on C programs but for C++ programs it tells the compiler to use the symbol names as created by the C compiler.
  #9  
Old 04-Nov-2008, 04:09
PC Nerd PC Nerd is offline
New Member
 
Join Date: Feb 2007
Posts: 13
PC Nerd is on a distinguished road

Re: Loading shared libraries - dlopen unknown reference - dlfcn not working?


Hey,
Short answer: - its workign thanks - your brilliant!

ok.

I had played so much with rewriting files in minGW directoyr that i decided to reinstall MinGW ( same directory same installer. etc). Anyway - I then completed your second set of instructions. Got duplicate output ( except the what I assume is the memory locations after some output in test.exe, thus mine was of course different).
Copied files across and test2.exe worked.

I then rewrite the dlfcn.h file with the __cplusplus addition and its all working on my project - so thanks!



Since you seem pretty knowledgable about this area of C++, once i want to go and distribute this to friends etc, do I have to package any of the dlfcn stuff into my installer and have it in my lib directory - or whats the deal? (New to C++ but definately not to programming so basic helloworld stuff isnt where I'm lingering on learning ).

Thanks
  #10  
Old 04-Nov-2008, 08:37
davekw7x davekw7x is offline
Outstanding Member
 
Join Date: Feb 2004
Location: Left Coast, USA
Posts: 5,217
davekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to beholddavekw7x is a splendid one to behold

Re: Loading shared libraries - dlopen unknown reference - dlfcn not working?


Quote:
Originally Posted by PC Nerd
...
I then rewrite the dlfcn.h file with the __cplusplus addition and its all working on my project
Huzzah!

Quote:
Originally Posted by PC Nerd
.
...to go and distribute..

The only real change in dlfcn distribution is to put the extern "C" lines in dlfcn.h.

According to the comments in the source files (*.c and *.h) they licensed under the Gnu Public License (GPL).

That means that you can modify the files any way that you want, and you can use and you can distribute the modified files as long as you don't delete anything about the copyright/license. That is, you can't remove the provisions of GPL and make it have some less-restrictive type of license (you can't put it in the public domain), and you can't make it have some more-restrictive type of license (you can't make it proprietary).

Bottom line: You can change the program part of the contents, and you can add comments, but do not delete the existing comments. Furthermore, anyone who gets your modified file can distribute it (with or without further modifications) as long as it remains GPL.

Regards,

Dave

Footnote: The Makefiles and config.mak that I posted here were written by me, and there are no copyright or license issues. I probably should have put in a comment that it is released to the public domain or some such thing. Anyhow, people are free to use anything that I write and post on this forum in any way that they want.
 
 

Recent GIDBlogOnce again, no time for hobbies by crystalattice

Thread Tools Search this Thread
Search this Thread:

Advanced Search
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

vB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Forum Jump

Similar Threads
Thread Thread Starter Forum Replies Last Post
Shared Libraries with qmake and Exception Handling PiJ C++ Forum 3 18-Dec-2007 10:29
Two-Tier data dissemination code installation problem nidhibansal1984 Computer Software Forum - Linux 6 16-Sep-2007 11:13
gnu.linkonce undefined reference newbie06 C++ Forum 4 13-Mar-2007 10:53
fltk-2.0 cvs Plumb FLTK Forum 20 13-Nov-2004 08:10

Network Sites: GIDNetwork · GIDWebHosts · GIDSearch · Learning Journal by J de Silva, The

All times are GMT -6. The time now is 04:33.


vBulletin, Copyright © 2000 - 2009, Jelsoft Enterprises Ltd.