Is it possible to call DLL functions from a Linux program?

Kevin Cousins kevin at proximity.com.au
Sun Apr 13 20:29:52 CDT 2003


On Mon, 2003-04-14 at 09:09, Eloy A. Paris wrote:
> Sorry if this has been covered before, but I could not find any
> answers in the archives or by Googling...

Yeah, I've been down that track recently myself! :)



> Here's the situation: I have a Windows DLL and a small Windows program
> that calls functions from this DLL...
> Now, I want to run this program natively under Linux - I mean, I don't
> want to run wcmd because that requires an X server.
> 
> The first question is: is this possible? (have a Unix program that
> calls functions from a native Windows DLL).

It sure is possible!



> I started experimenting
> with winelib, but am not sure if this is the correct way...

My (limited) experience suggests that using WineLib is the right way to
accomplish what you want.  There are other means, by which I mean that
there are a number of open source projects which have hacked the Wine
"loader" code: avifile; mplayer; xine, but they're most likely to work
with DLLs which call only a finite subset of the Windows API.



> If this is possible, how should I do it? I ran winemaker, configure,
> make, but am getting errors from winbebuild.

Hurdles I had to cross include:

1. I had built Wine below my home directory, but linking against it
   there produced unimpressive results.  I suspect that Wine is highly
   critical of attempts to look for it's DLLs anywhere other than below
   /usr/lib/wine (or, perhaps, to be generous, /usr/local/lib/wine).

   I got "sudo" permission from my sysadmin, installed Wine properly,
   and instantly had better success with WineLib.

2. Parameters to winemaker.  Parameters to configure are easy (with a
   properly installed Wine), also for make.  Because winebuild is called
   from make, we don't have much control over the parameters it sees.
   We've got to get the incantation to winemaker correct.

   I eventually went for the minimalist approach:

	--cuiexe --single-target foo.exe -L/home/kevin/lib

3. Code.  When your "application" finally links, you'll see -lwine on
   the compiler command line.  That's so that your application can call
   things like "LoadLibrary()" and "GetProcAddress()".  I found the text
   in <wine-src-root-dir>/documentation/HOWTO-winelib to be confusing,
   but ultimately suggestive of the path to take.

   What you *want* to do is to arrange for the following:

       WINE  ---loads-->  foo.exe  ---calls-->  bar.DLL


   What you *have* to do is subtly different:

       WINE  ---loads-->  foo.exe  ---runs-->  stub  ---loads-->  bar.DLL

   where it is suggested that "stub" be a "WineLib DLL", or, linked so
   as to be called "stub.dll.so".  I eventually decided to go without
   the stub.dll.so, but only after deciding to achieve the same result
   by linking equivalent code into my application.  I had problems in
   getting any WineLib DLL I produced to be correctly initialised, i.e.,
   to have it's DllMain() executed implicitly at LoadLibrary() time.  My
   way, I can control it explicily by making certain that my app call
   stub_init() explicitly.

   The intention is that "stub" should shadow the APIs in bar.DLL
   through function pointers.  Here's an example: bar.DLL exports a
   function called "int func(int)".  That prototype would already be
   exposed by the fubar.h header file.  You've basically got to write
   your own func(), like this.  Code in stub.c will look like:

     #include "fubar.h"
     #include <windows.h>
     static int (*func_pointer)(int);

     void stub_init() {
       HINSTANCE handle = LoadLibrary("fubar.dll");
       GetProcAddress(handle, "func", func_pointer);
     }

     int func(int x) {
       return func_pointer(x);
     }

Do that, or something similar, and you'll soon be smiling.



> P.S. I read the winelib user guide, but couldn't find the answer
> there. If it is there, it's not clear to me :(

Ha!  I know exactly what you mean!

It seems the Wine project in general suffers from a distinct lack of
good and relevant documentation.  Understand that there's also the
mailing list archives, somewhere on winehq.org, and the news group
comp.emulators.ms-windows.wine, you'll inevitably find heaps of
information in those two places if you spend long enough refining your
search keys.  Still, that's no substitute for good documentation.

Please let me know how you get on.

--
Kevin.




More information about the wine-devel mailing list