(a): Introduction
For some reason, you may find that you want to use your Linux library as you would with Windows DLLs. For this there are some reasons such as the following:
You are supporting a large application that uses multiple third-party libraries. The project is available in Linux, but you are not ready to link directly to him as a Linux shared library.
There is a well-defined interface available, and there are many workarounds for interfaces.
You only have a binary Windows app that he can extend through plug-ins, such as a text editor or IDE.
The process of dealing with these problems is very easy. You need to write a spec file that describes the narrative library interface as a DLL in the same format. Of course, You might want to write a small package for the library. You combine them into a wine built-in DLL that is linked to a Linux library. Then you change the thedlloverrides in the wine configuration to make sure that the new built-in DLL is called, not whatever the Windows version number is.
In this section, we will see two sample programs. The first example is very easy and introduces a theme in "Baby steps". All two examples are interface proxies for ODBC in wine. The file we will be referencing in the ODBC sample is located in the wine source code of dlls/ The Odbc32 folder.
The first example is based on a situation (for example, the function name has been changed to protect the innocent function). A large number of Windows apps include DLLs that are linked to third-party DLLs. For some reason, third-party DLLs do not perform well in wine. Then, The third party libraries is also available in Linux environments. Conveniently, DLLs and Linux shared libraries have only a small subset of functionality, and the application is only used by one of them.
In particular, the application calls a function:
signedshort WINAPI MyWinFunc (unsignedshortvoidvoid *c,unsignedlongvoidintcharunsignedchar *h);
The Linux library includes a corresponding function:
signedshort MyLinuxFunc (unsignedshortvoidvoid *c,unsignedshortvoidcharunsignedchar *h);
(ii): Preparation of spec documents
Start by writing a spec file. This file describes the narrative interface as if he were a DLL.
In this simple example, we want a wine built-in DLL and the Mywin DLL to correspond. spec files are MyWin.dll.spec and look like this:
# # File:MyWin.dll.spec # # some sort of copyright # # Wine spec file for the MyWin.dll built-in library (a minimal wrapper around the # Linux library Libmylinux) # # for further details of the wine spec files See the winelib documentation at # www.winehq.org 2 stdcall Mywinfunc ( long ptr ptr ptr ptr long long ptr) myproxywinfunc# End of File
Note that the parameters are marked long, even if they are smaller than that. In this example, we will link directly to the Linux shared library, and through the ODBC example we will dynamically load the Linux shared library.
In the ODBC sample, you can see these in the file Odbc32.spec.
(iii): Write a package
First, we're going to look at a simple example. The basic question of this example is the list of different strengths. The F-parameter does not have to be passed to the Linux function, and D-parameters theoretically need unsigned long * unsigned short * to be . This is done to ensure that the return value of the high position is set correctly. And unlike the ODBC sample, we're going to link directly to a shared library on Linux.
/* * FILE:MYWIN.C * * Copyright (c) the copyright holder. * * Basic Wine Wrapper for theLinux3RD Party Library so that itCan be * used by the Application* * currently thisfileMakes no attempt toBe a full wrapper for the 3RD * Party library;itOnly exports enough forOur own use. * * Note thatThis isA Unixfile; Please don ' t go convertingit toDOS format * (e.g. converting line feeds toCarriagereturn/line feed). * * Thisfileshould be builtinchA Wine environment asA winelib library, * linked to theLinux3RD party Libraries (currently libxxxx.so and* libyyyy.so) */#include <3rd Party linux header>#include <windef.h> * * Part of the Wine header files * */* This Declaration is asDefinedinch theSpecfile. It isDeliberately not* SpecifiedinchTerms of 3RD Party TypessinceWe are messing AboutHere *betweenOperating Systems (makingitLook like a Windows thing when * actuallyit isA Linux thing). In this thecompiler would point out any * inconsistencies. * For example the FourthArgument needs care */signed short WINAPI myproxywinfunc (unsigned short A, void *b, void *c,unsigned long *d, void *e, in T F, char G, unsigned char *h) {unsigned short D1; Signed short ret; D1 = (unsigned short) *d; RET =3RD Party Linux function (A, B, C, &D1, E, G, h); *d = D1;returnRET;} /* End of file*/
For a broader scenario, we can use the ODBC sample. This is implemented bit a header file (proxyodbc.h) and a C source code file (PROXYODBC.C). Although the file is long, it is structurally easy.
The DllMain function is used to initialize the DLL. In the procedure attach event, the function dynamically links to the desired Linux ODBC library (due to several available) and constructs a series of function pointers. In the process solution attach event, he removes the link.
Each function then invokes the appropriate Linux function through the function pointers set during initialization.
(iv): building
So how do we build a wine built-in DLL?
The simplest way is to make winemaker do these complicated work for us. For a simple example, we have two source code files (encapsulation and spec files). We also have third-party header files and library files.
Place the two source files in a suitable folder and use winemaker to create the build framework, including configuration scripts, makefile, and so on. You may want to use the following options:
--nosource-fix(need to winemaker version number 0.5 or update) to ensure that two files have not been altered (assuming that a lower version number is used, so that the two files are read-only, and ignore the complaint cannot be changed).
--dll --single-target MyWin --nomfcTo specify the target
--DMightNeedSomething -I3rd_party_include -L3rd_party_lib -lxxxx -lyyyyThe location of these header files, etc.
After executing winemaker, I was able to edit makefile just before the definition, adding a line to it CEXTRA = -Wall .
Then simply execute confugure and make.
(v): Installation
So how do we install the agent and make sure everything is connected correctly?
There is a great deal of flexibility in this matter, so it is not the only viable option that needs to be followed.
Make sure that the Linux shared object is placed where the Linux system can find it. This means that he should be placed in one of the folders mentioned in the/etc/ld.so.conf file or in a Ld_library_ path Specifies the following paths. If you can link to him from a Linux program, you should be able to.
Talk about proxy shared objects (MyWin.dll.so) in the same location as other parts of the built-in DLL. Make sure that the Winedllpath includes folders that have proxy shared objects.
Assuming you have both a Windows DLL and a Linux dll/proxy pair, then you have to make sure that you have the correct one to get the call. The simplest way is to rename the Windows version number so that he is not detected. You can use Winecfg to set a DLL rewrite, This allows the built-in version number to be used.
Once you do this, you should be able to successfully use a Linux shared object. Let's say you have a problem, and then set the WINEDEBUG=+module environment variables to see what really happened before you run wine.
(vi): Convert file name
Suppose you want to convert the file names in the incoming DOS format to their equivalent UNIX format. Of course, there is no proper function in Microsoft's Windows API, but wine provides a function for this work and is exported from a copy of the kernel32 DLL. This function is wine_get_unix_file_name(defined in winbase.h).
(eight): Building winelib DLLs