I'm using wine to access a particular proprietary DLL (I don't have the source for it) on Linux. The way I'm doing this is to write an EXE that wraps the DLL, and makes all of the functions available via socket request and response messages. My linux program has access to the functions of the DLL by sending socket messages to the EXE running under wine. 2 questions:
1. My DLL/EXE uses no calls to pop up graphical windows, so theoretically no display is needed. Of course wine needs a display because it does not know that an EXE won't make such calls. Is there a way to run wine with a null or dummy display - so that it is effectively running headless?
2. The sockets trick was the simplest way I could figure out how to do IPC between a linux process and a wine process. However, is there are any better or faster way to do this? As far as I know I can't use winelib because I don't have the source to the DLL.
Thanks,
Ken Larson
Ken Larson wrote:
I'm using wine to access a particular proprietary DLL (I don't have the source for it) on Linux. The way I'm doing this is to write an EXE that wraps the DLL, and makes all of the functions available via socket request and response messages. My linux program has access to the functions of the DLL by sending socket messages to the EXE running under wine. 2 questions:
- My DLL/EXE uses no calls to pop up graphical windows, so
theoretically no display is needed. Of course wine needs a display because it does not know that an EXE won't make such calls. Is there a way to run wine with a null or dummy display - so that it is effectively running headless?
- The sockets trick was the simplest way I could figure out how to do
IPC between a linux process and a wine process. However, is there are any better or faster way to do this? As far as I know I can't use winelib because I don't have the source to the DLL.
Thanks,
Ken Larson
If your program is a console-only app, it can run without an X server. For example, the command "regedit /?" works without defining a DISPLAY variable, even in a text console. If you write interesting information to a logfile instead of the screen, you could even do "wine wrapper.exe &" on the shell and put your app in the background.
About winelib, you could try making a winelib app that loads the DLL dynamically. But this would only work for a true DLL (for example "propietary.dll") on which you can call LoadLibrary(). If your library is a static one such as "propietary.lib", with no companion DLL file to load, then all the interesting code is in the LIB file itself and cannot be loaded dynamically.
About faster communication, you could try running the Linux app, which would fork(). One process runs your GUI or sets up your service, and the other could then exec() the winelib wrapper. Before the fork, you should set up a pair of pipes, or use socketpair() for communication. If you are careful, this can even work for a pure Windows app linked with a static LIB file, by connecting your pipe/socket to the stdin/stdout of the wine process (see the manpage on dup2() for details).
Hope this helps.
Alex Villacís Lasso
Alex -
Thanks for the good info. As far as not needing an X server, when I try to run my exe under wine without one, I get:
wine: Could not load graphics driver 'x11drv'. Make sure that your X server is running and that $DISPLAY is set correctly.
but yes, the regedit /? trick works fine.
I wonder if there is something obvious I'm missing in the compilation and linking of my EXE? Where might I look to make sure it doesn't think it needs a display.
My exe and the wrapped DLL do use sockets and I know that sockets in windows often need a window handle to do their thing...
My DLL is a true DLL as far as I know, I currently link to it using the accompanying .lib, but I think I could link dynamically to it.
Ken
Alex Villacís Lasso wrote:
Ken Larson wrote:
I'm using wine to access a particular proprietary DLL (I don't have the source for it) on Linux. The way I'm doing this is to write an EXE that wraps the DLL, and makes all of the functions available via socket request and response messages. My linux program has access to the functions of the DLL by sending socket messages to the EXE running under wine. 2 questions:
- My DLL/EXE uses no calls to pop up graphical windows, so
theoretically no display is needed. Of course wine needs a display because it does not know that an EXE won't make such calls. Is there a way to run wine with a null or dummy display - so that it is effectively running headless?
- The sockets trick was the simplest way I could figure out how to do
IPC between a linux process and a wine process. However, is there are any better or faster way to do this? As far as I know I can't use winelib because I don't have the source to the DLL.
Thanks,
Ken Larson
If your program is a console-only app, it can run without an X server. For example, the command "regedit /?" works without defining a DISPLAY variable, even in a text console. If you write interesting information to a logfile instead of the screen, you could even do "wine wrapper.exe &" on the shell and put your app in the background.
About winelib, you could try making a winelib app that loads the DLL dynamically. But this would only work for a true DLL (for example "propietary.dll") on which you can call LoadLibrary(). If your library is a static one such as "propietary.lib", with no companion DLL file to load, then all the interesting code is in the LIB file itself and cannot be loaded dynamically.
About faster communication, you could try running the Linux app, which would fork(). One process runs your GUI or sets up your service, and the other could then exec() the winelib wrapper. Before the fork, you should set up a pair of pipes, or use socketpair() for communication. If you are careful, this can even work for a pure Windows app linked with a static LIB file, by connecting your pipe/socket to the stdin/stdout of the wine process (see the manpage on dup2() for details).
Hope this helps.
Alex Villacís Lasso
Ken Larson wrote:
Alex -
Thanks for the good info. As far as not needing an X server, when I try to run my exe under wine without one, I get:
wine: Could not load graphics driver 'x11drv'. Make sure that your X server is running and that $DISPLAY is set correctly.
but yes, the regedit /? trick works fine.
I wonder if there is something obvious I'm missing in the compilation and linking of my EXE? Where might I look to make sure it doesn't think it needs a display.
My exe and the wrapped DLL do use sockets and I know that sockets in windows often need a window handle to do their thing...
My DLL is a true DLL as far as I know, I currently link to it using the accompanying .lib, but I think I could link dynamically to it.
Ken
It seems that you are using VisualC++ to compile your app. There is a wizard to create a new application, in which the user can select to create a "console app", one that runs from main() instead of WinMain(). Try creating such a skeleton app and running it from Wine. Once you succeed, you can start adding source files from your previous app into the skeleton console app. This would be the "blind" way of doing this - I don't remember much about the options available for creating a console app out of an arbitrary project in VisualC++. I know for a fact that console apps run without an X server in Wine, because I have just tested cl.exe from MS VisualStudio in a raw text console in Linux, after resolving a missing dll.
If the above *still* does not solve your problem (even after upgrading to the latest Wine CVS), you might try using a virtual framebuffer X server:
(output of yum xorg-x11-Xvfb): Name : xorg-x11-Xvfb Arch : i386 Version: 6.8.2 Release: 37.FC4.49.2 Size : 1.6 M Repo : updates-released Summary: A X Windows System virtual framebuffer X server. Description: Xvfb (X Virtual Frame Buffer) is an X server that is able to run on machines with no display hardware and no physical input devices. Xvfb simulates a dumb framebuffer using virtual memory. Xvfb does not open any devices, but behaves otherwise as an X display. Xvfb is normally used for testing servers.
You can try installing and configuring this X server. It will not output anything or use a console, but will behave otherwise like a valid X server. Then you should point the DISPLAY environment variable to this X server, and this will keep your app happy. However, I *strongly* recommend to try and create a true console-mode app before trying the virtual-framebuffer X server, because it will consume precious memory.
Alex Villacís Lasso
Alex Villacís Lasso wrote:
You can try installing and configuring this X server. It will not output anything or use a console, but will behave otherwise like a valid X server. Then you should point the DISPLAY environment variable to this X server, and this will keep your app happy. However, I *strongly* recommend to try and create a true console-mode app before trying the virtual-framebuffer X server, because it will consume precious memory.
You can also run a VNC server on the virtual X server. Then you can leave and connect to your session from any client computer, without shutting down your running X programs.
regards, Jakob
On Fri, 30 Sep 2005, Jakob Eriksson wrote:
Alex Villacís Lasso wrote:
You can try installing and configuring this X server. It will not output anything or use a console, but will behave otherwise like a valid X server. Then you should point the DISPLAY environment variable to this X server, and this will keep your app happy. However, I *strongly* recommend to try and create a true console-mode app before trying the virtual-framebuffer X server, because it will consume precious memory.
You can also run a VNC server on the virtual X server. Then you can leave and connect to your session from any client computer, without shutting down your running X programs.
If it's not really trying to do anything graphical, maybe you could use ttydrv instead of xdrv.
Well I am actually using a command-line with CL to compile it, but it was true that I had a WinMain instead of main.
I've changed the WinMain to main, but this doesn't seem to be the issue.
The issue appears to be initializing winsock. The following simple main program, when compiled with CL, and run with wine, requires an X display:
#include <windows.h> #include <winsock.h>
int main(int argc, const char *argv[]) { WORD sockVersion; WSADATA wsaData;
sockVersion = MAKEWORD(1, 1);
WSAStartup(sockVersion, &wsaData);
}
Remove the call to WSAStartup, and the program requires no X display.
As I said, I know winsock uses hidden windows handles to do some things, which is pretty ugly architecturally. However, it seems like it should be possible to not have a display in this case. any ideas?
I do like the idea of using winelib and having my wrapper be compiled under linux in winelib, but the proprietary DLL I am using also uses winsock so I would expect to have the same problem.
Thanks,
Ken
Alex Villacís Lasso wrote:
Ken Larson wrote:
Alex -
Thanks for the good info. As far as not needing an X server, when I try to run my exe under wine without one, I get:
wine: Could not load graphics driver 'x11drv'. Make sure that your X server is running and that $DISPLAY is set correctly.
but yes, the regedit /? trick works fine.
I wonder if there is something obvious I'm missing in the compilation and linking of my EXE? Where might I look to make sure it doesn't think it needs a display.
My exe and the wrapped DLL do use sockets and I know that sockets in windows often need a window handle to do their thing...
My DLL is a true DLL as far as I know, I currently link to it using the accompanying .lib, but I think I could link dynamically to it.
Ken
It seems that you are using VisualC++ to compile your app. There is a wizard to create a new application, in which the user can select to create a "console app", one that runs from main() instead of WinMain(). Try creating such a skeleton app and running it from Wine. Once you succeed, you can start adding source files from your previous app into the skeleton console app. This would be the "blind" way of doing this - I don't remember much about the options available for creating a console app out of an arbitrary project in VisualC++. I know for a fact that console apps run without an X server in Wine, because I have just tested cl.exe from MS VisualStudio in a raw text console in Linux, after resolving a missing dll.
If the above *still* does not solve your problem (even after upgrading to the latest Wine CVS), you might try using a virtual framebuffer X server:
(output of yum xorg-x11-Xvfb): Name : xorg-x11-Xvfb Arch : i386 Version: 6.8.2 Release: 37.FC4.49.2 Size : 1.6 M Repo : updates-released Summary: A X Windows System virtual framebuffer X server. Description: Xvfb (X Virtual Frame Buffer) is an X server that is able to run on machines with no display hardware and no physical input devices. Xvfb simulates a dumb framebuffer using virtual memory. Xvfb does not open any devices, but behaves otherwise as an X display. Xvfb is normally used for testing servers.
You can try installing and configuring this X server. It will not output anything or use a console, but will behave otherwise like a valid X server. Then you should point the DISPLAY environment variable to this X server, and this will keep your app happy. However, I *strongly* recommend to try and create a true console-mode app before trying the virtual-framebuffer X server, because it will consume precious memory.
Alex Villacís Lasso
Remove the call to WSAStartup, and the program requires no X display.
As I said, I know winsock uses hidden windows handles to do some things, which is pretty ugly architecturally. However, it seems like it should be possible to not have a display in this case. any ideas?
It looks like the only dependency is from the PostMessageA in dlls/winsock/async.c #514.
The windows version of ws2_32.dll does not link to user32.dll however, it appears to load it on demand. I can see the following strings in it:
USER32.dll TranslateMessage PeekMessageA PostMessageA DispatchMessageA
Seems like it wouldn't be too hard to change the PostMessageA to LoadLibrary/GetProcAddres.
Mike
"Mike McCormack" mike@codeweavers.com wrote:
It looks like the only dependency is from the PostMessageA in dlls/winsock/async.c #514.
The windows version of ws2_32.dll does not link to user32.dll however, it appears to load it on demand. I can see the following strings in it:
USER32.dll TranslateMessage PeekMessageA PostMessageA DispatchMessageA
Seems like it wouldn't be too hard to change the PostMessageA to LoadLibrary/GetProcAddres.
depends.exe shows that ws2_32 has a delay load dependency on user32. We have to move user32 to a delay loaded section as well in our version.
Dmitry Timoshkov wrote:
"Mike McCormack" mike@codeweavers.com wrote:
It looks like the only dependency is from the PostMessageA in dlls/winsock/async.c #514.
The windows version of ws2_32.dll does not link to user32.dll however, it appears to load it on demand. I can see the following strings in it:
USER32.dll TranslateMessage PeekMessageA PostMessageA DispatchMessageA
Seems like it wouldn't be too hard to change the PostMessageA to LoadLibrary/GetProcAddres.
depends.exe shows that ws2_32 has a delay load dependency on user32. We have to move user32 to a delay loaded section as well in our version.
So do I interpret this to mean there is a plan to change this in wine? That would be great.
The proprietary DLL I call also uses winsock, I do not know whether synchronous or asynchronous, but is it then true that even if this dependency were changed to "delay", that if the DLL I'm calling opens an async socket (which uses a (non-visible) window handle for the notifications), that wine would require the X windows display at that point and fail anyway?
Thanks,
Ken
"Ken Larson" x1@larsontechnologies.com wrote:
depends.exe shows that ws2_32 has a delay load dependency on user32. We have to move user32 to a delay loaded section as well in our version.
So do I interpret this to mean there is a plan to change this in wine? That would be great.
I sent a patch to wine-patches which makes user32 a delay loaded dependency for ws2_32 yesterday.
Ken Larson wrote:
Well I am actually using a command-line with CL to compile it, but it was true that I had a WinMain instead of main.
I've changed the WinMain to main, but this doesn't seem to be the issue.
The issue appears to be initializing winsock. The following simple main program, when compiled with CL, and run with wine, requires an X display:
Your minimal winsock program doesn't need X when cross-compiled with mingw, and runs happily using winetty.drv
$ i586-mingw32msvc-gcc winsock.c -l wsock32
$ WINEDEBUG=loaddll DISPLAY= ~/wine/wine-20050830/wine ./a.exe ... trace:loaddll:load_builtin_dll Loaded module L"c:\windows\system32\winex11.drv" : builtin trace:loaddll:MODULE_FlushModrefs Unloaded module L"c:\windows\system32\winex11.drv" : builtin trace:loaddll:load_builtin_dll Loaded module L"c:\windows\system32\winetty.drv" : builtin $
Richard.
cool, can you point me to where i can find the info on how to easily set up this cross-compiler on linux?
thanks,
Ken
Richard Cohen wrote:
Ken Larson wrote:
Well I am actually using a command-line with CL to compile it, but it was true that I had a WinMain instead of main.
I've changed the WinMain to main, but this doesn't seem to be the issue.
The issue appears to be initializing winsock. The following simple main program, when compiled with CL, and run with wine, requires an X display:
Your minimal winsock program doesn't need X when cross-compiled with mingw, and runs happily using winetty.drv
$ i586-mingw32msvc-gcc winsock.c -l wsock32
$ WINEDEBUG=loaddll DISPLAY= ~/wine/wine-20050830/wine ./a.exe ... trace:loaddll:load_builtin_dll Loaded module L"c:\windows\system32\winex11.drv" : builtin trace:loaddll:MODULE_FlushModrefs Unloaded module L"c:\windows\system32\winex11.drv" : builtin trace:loaddll:load_builtin_dll Loaded module L"c:\windows\system32\winetty.drv" : builtin $
Richard.
On Sunday 25 September 2005 05:37, Ken Larson wrote:
I'm using wine to access a particular proprietary DLL (I don't have the source for it) on Linux. The way I'm doing this is to write an EXE that wraps the DLL, and makes all of the functions available via socket request and response messages. My linux program has access to the functions of the DLL by sending socket messages to the EXE running under wine. 2 questions:
- My DLL/EXE uses no calls to pop up graphical windows, so
theoretically no display is needed. Of course wine needs a display because it does not know that an EXE won't make such calls. Is there a way to run wine with a null or dummy display - so that it is effectively running headless?
- The sockets trick was the simplest way I could figure out how to do
IPC between a linux process and a wine process. However, is there are any better or faster way to do this? As far as I know I can't use
Your .exe can make regular linux syscalls as it's really running on linux. So you can essentially do whatever a regular linux application would, given constraints enforced by wine's signal handling and such. But all simple things like opening a pipe, using ipc() call etc will work. The only thing is that you need to code syscall() and a couple of wrappers for specific syscalls you want to use, but that's a simple matter and glibc sources are a reasonable reference for that.
Cheers, Kuba
Kuba Ober wrote:
On Sunday 25 September 2005 05:37, Ken Larson wrote:
I'm using wine to access a particular proprietary DLL (I don't have the source for it) on Linux. The way I'm doing this is to write an EXE that wraps the DLL, and makes all of the functions available via socket request and response messages. My linux program has access to the functions of the DLL by sending socket messages to the EXE running under wine. 2 questions:
- My DLL/EXE uses no calls to pop up graphical windows, so
theoretically no display is needed. Of course wine needs a display because it does not know that an EXE won't make such calls. Is there a way to run wine with a null or dummy display - so that it is effectively running headless?
- The sockets trick was the simplest way I could figure out how to do
IPC between a linux process and a wine process. However, is there are any better or faster way to do this? As far as I know I can't use
Your .exe can make regular linux syscalls as it's really running on linux. So you can essentially do whatever a regular linux application would, given constraints enforced by wine's signal handling and such. But all simple things like opening a pipe, using ipc() call etc will work. The only thing is that you need to code syscall() and a couple of wrappers for specific syscalls you want to use, but that's a simple matter and glibc sources are a reasonable reference for that.
Cheers, Kuba
This assumes that I'm using winelib, correct? (I currently am not, I'm compiling on windows, but considering using winelib instead)
Thanks,
Ken
- The sockets trick was the simplest way I could figure out how to do
IPC between a linux process and a wine process. However, is there are any better or faster way to do this? As far as I know I can't use
Your .exe can make regular linux syscalls as it's really running on linux. So you can essentially do whatever a regular linux application would, given constraints enforced by wine's signal handling and such. But all simple things like opening a pipe, using ipc() call etc will work. The only thing is that you need to code syscall() and a couple of wrappers for specific syscalls you want to use, but that's a simple matter and glibc sources are a reasonable reference for that.
This assumes that I'm using winelib, correct?
Why so? I explicitly mention the .exe. So, no winelib. To the contrary, this assumes that you run your regular .exe under wine.
There's nothing linux-only about generating syscall code, you can compile your .exe program say using mingw or Visual C++ as long as you've properly implemented syscall() in [inline] assembly. Presumably, the calling conventions for such a syscall() can be set such that the stack layout will match. Just have a look at the glibc sources.
Of course the program will crash on windows, but on linux it should just work and provide a gateway to calling the functions from the .dll that you need. That's what you're after, right?
Cheers, Kuba
Ken Larson wrote:
This assumes that I'm using winelib, correct? (I currently am not, I'm compiling on windows, but considering using winelib instead)
Yes!! Winelib can be both your DLL calling code, and you complete Linux application. No need for .EXE compiled or crosscompiled for windows, No need for IPC and no need for two parts at all. I apologize for the State of the documentation that this is not clear!
It as been proven that any windows code can be compiled as Winelib. If you are using core Libraries like MFC or ATL than that might get difficult (not impossible), but it seems this is not your case. On the other hand Winelib applications are a Linux applications so they can link to any Linux library. Just that they have a funny Makefile and are built with Winegcc.
Statically linking of a DLL is done as follows: - Write a .spec file prototyping your DLL, than “winebuild” it to a .DEF file. (make a rule for it in Makefile) - Link your Winelib against that .DEF file like you do any other Wine/Native DLL.
.spec file syntax is documented and should be simple. Now all this is easy if your DLL is extern "C". If it is C++ exports you'll need something extra. Is your DLL exporting C++ mangled symbols?
Free Life Boaz
Boaz Harrosh wrote:
Ken Larson wrote:
This assumes that I'm using winelib, correct? (I currently am not, I'm compiling on windows, but considering using winelib instead)
Yes!! Winelib can be both your DLL calling code, and you complete Linux application. No need for .EXE compiled or crosscompiled for windows, No need for IPC and no need for two parts at all. I apologize for the State of the documentation that this is not clear!
It as been proven that any windows code can be compiled as Winelib. If you are using core Libraries like MFC or ATL than that might get difficult (not impossible), but it seems this is not your case. On the other hand Winelib applications are a Linux applications so they can link to any Linux library. Just that they have a funny Makefile and are built with Winegcc.
Statically linking of a DLL is done as follows:
- Write a .spec file prototyping your DLL, than “winebuild” it to a .DEF
file. (make a rule for it in Makefile)
- Link your Winelib against that .DEF file like you do any other
Wine/Native DLL.
.spec file syntax is documented and should be simple. Now all this is easy if your DLL is extern "C". If it is C++ exports you'll need something extra. Is your DLL exporting C++ mangled symbols?
Free Life Boaz
Thanks for the info.
Ultimately, my app is a Java app. I am spawning my EXE wrapper around my DLL and talking to it from Java with sockets. So unless I'm missing something, my entire (Java) app can't be a winelib linux app (barring something like gcj which I'm not sure I'm ready for).
Ken
Ken Larson wrote:
Thanks for the info.
Ultimately, my app is a Java app.
If I recall correctly someone has reported Installation of Sun's Java for windows under wine. Or was it A failure to install? I can't recall. How would you call a DLL on Windows?
Free Life Boaz
Boaz Harrosh wrote:
Ken Larson wrote:
Thanks for the info.
Ultimately, my app is a Java app.
If I recall correctly someone has reported Installation of Sun's Java for windows under wine. Or was it A failure to install? I can't recall. How would you call a DLL on Windows?
Free Life Boaz
Typically, you call a native dll by using JNI, java native interface. You end up having to write your own DLL in C/C++ using the JNI specification, which can in turn do anything that C/C++ can do. If Java itself were running under wine, then we could of course run the entire app under wine, and there would be no need to write an EXE wrapper around the proprietary DLL I need to call. That is exactly how our windows verison functions: the Java code uses JNI to call a DLL that in turn calls the proprietary DLL.
This is probably not necessary since the original mechanism I mentioned, spawning and EXE under wine which communicates with Java on Linux using sockets, functions fine - apart from the minor issue of requiring a display, and perhaps some performance overhead. Then I am able to use the Linux version of Java (with the correct GUI look and feel, etc.).
Really I think the problem kind of comes down to this: as far as I know, you can create an executable with winelib, but you can't just create a library, right? That is, if I wanted to create a .so on linux using winelib, that java can load, I can't, because it has to be a program with a main, right? This is why I wrapped my DLL using and EXE and then run it as a child process.
Ken
On Mon, 3 Oct 2005, Boaz Harrosh wrote:
Ken Larson wrote:
Thanks for the info.
Ultimately, my app is a Java app.
If I recall correctly someone has reported Installation of Sun's Java for windows under wine. Or was it A failure to install? I can't recall. How would you call a DLL on Windows?
Sun's JVM installs and runs.
- Walter
Ken Larson wrote:
Thanks for the info.
Ultimately, my app is a Java app. I am spawning my EXE wrapper around my DLL and talking to it from Java with sockets. So unless I'm missing something, my entire (Java) app can't be a winelib linux app (barring something like gcj which I'm not sure I'm ready for).
Maybe crazy, but can't you make a wrapper winelib app which spawns Java?
//Jakob
Hi Ken,
On Sunday 25 Sep 2005 10:37, Ken Larson wrote:
- The sockets trick was the simplest way I could figure out how to
do IPC between a linux process and a wine process. However, is there are any better or faster way to do this? As far as I know I can't use winelib because I don't have the source to the DLL.
Apologies if this is all obvious ...
However you do your IPC, you'll suffer from having to do context switching from changing between the different processes (server & client). Depending on the application, there might be merit in bunching requests together and processing them in one batch.
That aside, there's additional overhead from the communication between the two tasks, which you can do in a number of ways (sockets, pipes, ...). Using shared memory (e.g. the SysV shmget() call) would allow the two processes to share parameters, results, etc with no [*] overhead.
[*] not quite true (kernel might need to do some page fetching, for example) , but near enough.
HTH,
Paul.