This is the mail archive of the cygwin mailing list for the Cygwin project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: Problem with dlopen()


On Nov  1 20:21, Juan Jose Garcia-Ripoll wrote:
> This function does some nonstandard things, but the most annoying one
> is imposing that the library to be loaded has to have a file
> extension.
> 
> If I invoke dlopen("/path/to/temp/dir/temporary_file", ...) then the
> routine fails with an error like "File or directory does not exist".
> It is probably not that text, but something similar output by
> dlerror(). If I rename the file as "temporary_file.foo" then dlopen()
> succeeds.
> 
> Using strace reveals that in the first case dlopen() is adding the
> extension ".dll" and complaining that the file does not exist. In
> addition to this, the file has to be given executable permissions
> using chmod() or dlopen will fail.
> 
> The reason I found this bug is that ECL (Embeddable Common Lisp)
> compiles lisp files to DLLs and uses nonstandard names for that. With
> mingw32 and Microsoft Visual Studio C++ we never had a problem, but
> cygwin broke when we used our code.

I'm somewhat puzzled by this, for two reasons:

- dlopen() uses LoadLibrary() under the hood.  With Mingw32 or VC++ you
  have to do the same, apparently.  LoadLibrary appends the .dll
  extension by itself(*) if the given filename has no extension.  So, if
  you had a shared lib called "foo", and you called LoadLibrary ("foo"),
  then you should have seen en error in MingW32/VC++.  Only by adding a
  trailing dot, you can avoid automative adding of the .dll suffix, same
  as in Cygwin's dlopen() function.

- If the library is not executable, the LoadLibrary function returns
  an "access denied" error.  You should have this observed, too.

Try this:

  $ cat > x.c << EOF
  #include <windows.h>
  #include <stdio.h>

  int main (int argc, char **argv)
  {
    HMODULE m = LoadLibrary (argv[1]);
    if (!m)
      printf ("%s: %lu\n", argv[1], GetLastError ());
    else
      printf ("Success\n");
    return 0;
  }
  EOF
  $ gcc x.c -o x
  $ cp /bin/cygncurses-9.dll ./xdll.dll
  $ ls -l xdll.dll
  -rwxr-xr-x 1 corinna vinschen 167936 2009-11-02 14:01 xdll.dll
  $ ./x xdll
  Success
  $ mv xdll.dll xdll
  $ ./x xdll
  xdll: 126
  $ net helpmsg 126

  The specified module could not be found.
 
  $ ./x xdll.        # Note the extra dot!
  Success
  $ chmod -x xdll
  $ ls -l xdll
  -rw-r--r-- 1 corinna vinschen 167936 2009-11-02 14:01 xdll
  $ ./x xdll.
  xdll.: 5
  $ net helpmsg 5

  Access is denied.

  $ mv xdll xdll.dll # Even with a dll suffix, you need execute permissions
  $ ./x xdll
  xdll: 5
  $ ./x xdll.dll
  xdll.dll: 5


Corinna

(*) http://msdn.microsoft.com/en-us/library/ms684175%28VS.85%29.aspx


-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat

--
Problem reports:       http://cygwin.com/problems.html
FAQ:                   http://cygwin.com/faq/
Documentation:         http://cygwin.com/docs.html
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]