Hello,
is it possible to link Win32 Wine libraries (*.dll.so) with a Linux application. Suppose we have a simple Linux gcc program main.cc
#include <vfw.h> int main(int argc, char** argv) { AVIFileInit(); }
which utilizes Win32 library features. When I try to compile it and link I do not have any problems:
g++ -Wall -g main.cc -lavifil32 -o main
But when I execute it I get a segmentation fault. Is there any way to avoid it ? May be I have to link other libraries ? Is it possible at all to dynamically link Wine libraries with Linux gcc-compiled code ?
Thank you.
On Thu, 20 Oct 2005 03:05, Vitaliy Margolen wrote:
Wednesday, October 19, 2005, 10:47:11 AM, Alexander Efremov wrote:
Hello,
is it possible to link Win32 Wine libraries (*.dll.so) with a Linux application. Suppose we have a simple Linux gcc program main.cc
Yes. It is called winelib application.
Actually, the answer to the original question is "no". It is not possible to just link the Wine libraries directly into a Linux application - at least not without additional work. A Winelib application (linked with winegcc) is itself a library which is loaded by one of the Wine executables (there is a patch to make Winelib applications into executables in their own right, but the patch is out of date).
There are a number of mechanisms by which a Linux application might be able to link directly to Wine libraries, but they all involve something more complex than the example provided.
As a developer of several applications that need to run on Windows and *nix, I am VERY interested in knowing more about the possible ways to accomplish this, and would be more than willing to help update whatever stuff is required.
At 04:52 PM 10/19/2005, Troy Rollo wrote:
On Thu, 20 Oct 2005 03:05, Vitaliy Margolen wrote:
Wednesday, October 19, 2005, 10:47:11 AM, Alexander Efremov wrote:
Hello,
is it possible to link Win32 Wine libraries (*.dll.so) with a Linux application. Suppose we have a simple Linux gcc program main.cc
Yes. It is called winelib application.
Actually, the answer to the original question is "no". It is not possible to just link the Wine libraries directly into a Linux application - at least not without additional work. A Winelib application (linked with winegcc) is itself a library which is loaded by one of the Wine executables (there is a patch to make Winelib applications into executables in their own right, but the patch is out of date).
There are a number of mechanisms by which a Linux application might be able to link directly to Wine libraries, but they all involve something more complex than the example provided.
On Thu, 20 Oct 2005 13:12, Rob D wrote:
As a developer of several applications that need to run on Windows and *nix, I am VERY interested in knowing more about the possible ways to accomplish this, and would be more than willing to help update whatever stuff is required.
There is an old patch for linking a Winelib as an ordinary executable file on wiki.winehq.org
There was also some discussion last year with the Mono people that suggested a system involving the use of longjmp from a WinMain back to the "main" program loop, which would ensure that Wine initialisation had taken place, although this might create problems for exception handling, and you may have to deallocate a bunch of memory Wine pre-allocates to make that system work.
Another technique would be to use a custom ctr0.o which caused a custom WinMain to be called that then called on to "main", thus running the Linux executable on the Wine stack.
Another approach would be to use the preprocessor to redefine "main" to something else in your real "main", then have a "main" in a separate module that called the Wine initialisation code, and a WinMain that called the renamed "main".
Thursday, October 20, 2005, 6:21:57 AM, you wrote:
On Thu, 20 Oct 2005 13:12, Rob D wrote:
As a developer of several applications that need to run on Windows and *nix, I am VERY interested in knowing more about the possible ways to accomplish this, and would be more than willing to help update whatever stuff is required.
There is an old patch for linking a Winelib as an ordinary executable file on wiki.winehq.org
Actually my problem is little bit different. I'm creating a library for Linux which utilizes some features of other Linux libraries + additionally I wand to utilize the avifil32.dll for the AVI stuff. The architecture is somethink like
|Linux Executable| --uses--> |Linux *.a and *.so libraries| + + |my Linux *.so library| --uses--> |Other Linux *.a and *.so libraries + WineLib avifil32.dll.so|
It's very pitty that we have all the features of Win32 *.dll libraies reimplemened for Linux but can't use them without the emulator.
By the way what exactly causes the segmentation fault during the execution ?
A also tried to compile and link WineLib *.dll.so applications using normal g++ for compilation and linking - just ignoring all the resource files - and it worked. I only had probles of some unresolved references when I link compiled in such a way dynamic libraries to an executable. Some stuff (which I guess <winebuild> adds) was unresolved. I also tried to link additionally the stuff generated by <winebuild> to the libraries but at the end i got the same segmantation fault :-(
Please HeLp !!! ;-)
On 10/20/05, Alexander Efremov vilgus@gmail.com wrote:
Actually my problem is little bit different. I'm creating a library for Linux which utilizes some features of other Linux libraries + additionally I wand to utilize the avifil32.dll for the AVI stuff. The architecture is somethink like
|Linux Executable| --uses--> |Linux *.a and *.so libraries| +
- |my Linux *.so library| --uses--> |Other Linux *.a and *.so
libraries + WineLib avifil32.dll.so|
It's very pitty that we have all the features of Win32 *.dll libraies reimplemened for Linux but can't use them without the emulator.
Yeah, but that's the way it is. Here's what I'd suggest: write a little Winelib program that offers avifil32 services via Unix domain sockets. Then make your Linux library run that program and connect to it via unix domain sockets. Voila, problem solved! Now you just have to figure out a way to split up your original idea for a library into two halves connected by a socket, which is a pain but will at least avoid the hell you're currently in.
You might be tempted to pursue another, much more ambitious alternative by making something like 'minwine' analogous to mingw32, i.e. strip Wine down to the parts that can just link into a normal linux app. It would have to be able to load video codec DLLs to be useful, which might be difficult. I wouldn't try this route if you want to get anything done and usable in the short term.
Dan Kegel wrote:
On 10/20/05, Alexander Efremov vilgus@gmail.com wrote:
Actually my problem is little bit different. I'm creating a library for Linux which utilizes some features of other Linux libraries + additionally I wand to utilize the avifil32.dll for the AVI stuff. The architecture is somethink like
|Linux Executable| --uses--> |Linux *.a and *.so libraries| +
- |my Linux *.so library| --uses--> |Other Linux *.a and *.so
libraries + WineLib avifil32.dll.so|
It's very pitty that we have all the features of Win32 *.dll libraies reimplemened for Linux but can't use them without the emulator.
You might be tempted to pursue another, much more ambitious alternative by making something like 'minwine' analogous to mingw32, i.e. strip Wine down to the parts that can just link into a normal linux app. It would have to be able to load video codec DLLs to be useful, which might be difficult. I wouldn't try this route if you want to get anything done and usable in the short term.
Isn't this exactly what mplayer is doing? Afair "look at how mplayer is doing" was a much used answer to people wanting to connect to their Windows DLLs which did few or no Win32 calls at all.
bye michael
Hello Michael,
Thursday, October 20, 2005, 3:48:13 PM, you wrote:
You might be tempted to pursue another, much more ambitious alternative by making something like 'minwine' analogous to mingw32, i.e. strip Wine down to the parts that can just link into a normal linux app. It would have to be able to load video codec DLLs to be useful, which might be difficult. I wouldn't try this route if you want to get anything done and usable in the short term.
Isn't this exactly what mplayer is doing? Afair "look at how mplayer is doing" was a much used answer to people wanting to connect to their Windows DLLs which did few or no Win32 calls at all.
That is exactly what I'm trying to do right now. The question is if they have the *general* solution for any *.dll or an adhoc approach for each *.dll they used. Did anyone try to repeat their trick or use their wrapper ?
Alexander Efremov wrote:
Hello Michael,
Thursday, October 20, 2005, 3:48:13 PM, you wrote:
You might be tempted to pursue another, much more ambitious alternative by making something like 'minwine' analogous to mingw32, i.e. strip Wine down to the parts that can just link into a normal linux app. It would have to be able to load video codec DLLs to be useful, which might be difficult. I wouldn't try this route if you want to get anything done and usable in the short term.
Isn't this exactly what mplayer is doing? Afair "look at how mplayer is doing" was a much used answer to people wanting to connect to their Windows DLLs which did few or no Win32 calls at all.
That is exactly what I'm trying to do right now. The question is if they have the *general* solution for any *.dll or an adhoc approach
Nope, it is not a general solution, it works only for the codecs dlls which seem to have a well defined API. Don't know exact details as i never looked at that code or Wine code in that area.
for each *.dll they used. Did anyone try to repeat their trick or use their wrapper ?
Projects that used similar techniques are CaptiveNTFS and maybe NDIS Wrapper.
bye michael
"Alexander Efremov" vilgus@gmail.com wrote:
Isn't this exactly what mplayer is doing? Afair "look at how mplayer is doing" was a much used answer to people wanting to connect to their Windows DLLs which did few or no Win32 calls at all.
That is exactly what I'm trying to do right now. The question is if they have the *general* solution for any *.dll or an adhoc approach for each *.dll they used. Did anyone try to repeat their trick or use their wrapper ?
Ones the DLL you are trying to use attempts to create a thread or access thread local storage it will immediately crash. That's why using Wine DLLs is not going to work very well outside of the full emulation environment. Think also about DOS file names and unix file names, somebody have to provide that functionality. That's an infinite loop: just have a look at the avifil32 dependencies.
On Thursday 20 October 2005 22:45, Alexander Efremov wrote:
The architecture is somethink like
|Linux Executable| --uses--> |Linux *.a and *.so libraries| +
- |my Linux *.so library| --uses--> |Other Linux *.a and *.so
libraries + WineLib avifil32.dll.so|
OK, then you will need to use the longjmp method.
By the way what exactly causes the segmentation fault during the execution ?
Something (and it could be one of many things) that is not initialised when you call the library.
A also tried to compile and link WineLib *.dll.so applications using normal g++ for compilation and linking - just ignoring all the resource files - and it worked... but at the end i got the same segmantation fault :-(
That is what I would expect. You can't just use normal g++ - winegcc is doing a lot of magic stuff for Wine.
It looks like you are going to have to use the longjmp method. Create a WineLib application whose WinMain just jumps back to some other routine. It will probably be worth patching winegcc and the Wine launcher code so that winegcc marks the executable at 3Gig-aware (based on a flag to winegcc) and the Wine launcher code recognises the flag and avoids reserving the 2-3G part of the address space. This should be enough that you can avoid mucking about with stacks and unmapping stuff wine has mapped.
You should have an arrangement that looks something like this:
1. Your DLL that wants to call the Win32 API links to a "startwinelib.so" with an entry point "start_wine_lib_for_dll".
2. "startwinelib.so" is a winelib app. "start_wine_lib_for_dll" would contain a "setjmp" followed by a call to wine_init, passing a dummied up argv that tells wine to start "startwinelib.so".
3. WinMain in "startwinelib.so" does a longjmp back to "start_wine_lib_for_dll"
4. From this point on you should be able to call the Win32 API as much as you like, even from files compiled with plain old gcc or g++.
5. You may need to set up an exception frame that does something like calling "exit" after printing a message about there being an unhandled exception.
Hello Troy,
Thursday, October 20, 2005, 10:49:18 PM, you wrote:
OK, then you will need to use the longjmp method.
I do not know what is "longjmp" method :-(
You should have an arrangement that looks something like this:
1. Your DLL that wants to call the Win32 API links to a "startwinelib.so" with an entry point "start_wine_lib_for_dll".
I do not have a DLL which wants to use the Win32 APIs. I have a Linux dynamic library (*.so) which wants to use the Win32 APIs.
2. "startwinelib.so" is a winelib app. "start_wine_lib_for_dll" would contain a "setjmp" followed by a call to wine_init, passing a dummied up argv that tells wine to start "startwinelib.so".
What is "setjmp" - an assembler directive ? Is <startwinelib.so> a standard WineLib application or I have to create it myself ?
3. WinMain in "startwinelib.so" does a longjmp back to "start_wine_lib_for_dll"
:-( What is "longjmp" exactly and how it should look like ? Unfortunatelly I'm not familiar with the assembler too much, and I know little about Wine :-(
3.1 Before calling Win32 entry points (other than those in the Win32 kernel) you will need to call LoadLibrary on the library they are in. This will ensure that Wine has initialised anything in the library that needs to be initialised.
Is LoadLibrary a Wine feature or Windows feature ?
4. From this point on you should be able to call the Win32 API as much as you like, even from files compiled with plain old gcc or g++.
This means that I link that magic <startwinelib.so> + other Win32 libraries which I need (like -lavifil32) to my Linux executable (or Linux dynamic library *.so) and everything will work out of box ? But what is the key point in this approach ? I do not use any functions in <startwinelib.so> - just link it to my Linux application and it will work ?!
5. You may need to set up an exception frame that does something like calling "exit" after printing a message about there being an unhandled exception.
Thank you very much.
On 10/21/05, Alexander Efremov vilgus@gmail.com wrote:
:-( What is "longjmp" exactly and how it should look like ?
... Is LoadLibrary a Wine feature or Windows feature ?
Use the Web, Luke! google takes you right to the man page for each of these.
I suspect you're getting in over your head here, but if you're a strong swimmer, you *might* survive :-)
BTW, have you checked to make sure there aren't already open source projects that do what your library will do? (I swear I saw one at sf.net the other day, but I can't find it at the moment.) - Dan
Hello Dan,
Friday, October 21, 2005, 5:08:44 PM, you wrote:
Use the Web, Luke! google takes you right to the man page for each of these.
I suspect you're getting in over your head here, but if you're a strong swimmer, you *might* survive :-)
BTW, have you checked to make sure there aren't already open source projects that do what your library will do? (I swear I saw one at sf.net the other day, but I can't find it at the moment.)
- Dan
:-(
If I had found the similar library (or at least something similar) I wouldn't have asked this question. If you could provide me with avifil32.dll functionalities for Linux I would really appreciate it. This library allows you to have different types of streams (not only video or audio) inside an *.avi file. And this is exectly what I need for my project. All existing Linux implementations of AVI functionalities (ffmpeg, xine, avifile, etc.) stick to the assumption that *.avi file can consist of only video and audio streams.
On 10/21/05, Alexander Efremov vilgus@gmail.com wrote:
If you could provide me with avifil32.dll functionalities for Linux I would really appreciate it. This library allows you to have different types of streams (not only video or audio) inside an *.avi file. And this is exectly what I need for my project. All existing Linux implementations of AVI functionalities (ffmpeg, xine, avifile, etc.) stick to the assumption that *.avi file can consist of only video and audio streams.
Have you considered enhancing one of those implementations? It might be easier... - Dan
OK, then you will need to use the longjmp method.
I missed a step...
Before calling Win32 entry points (other than those in the Win32 kernel) you will need to call LoadLibrary on the library they are in. This will ensure that Wine has initialised anything in the library that needs to be initialised.