121 lines
4.1 KiB
Plaintext
121 lines
4.1 KiB
Plaintext
|
<sect1 id="dll"><title>Building and Using DLLs</title>
|
||
|
|
||
|
<para>DLLs are Dynamic Link Libraries, which means that they're linked
|
||
|
into your program at run time instead of build time. There are three
|
||
|
parts to a DLL:</para>
|
||
|
|
||
|
<itemizedlist spacing="compact">
|
||
|
<listitem><para> the exports </para></listitem>
|
||
|
<listitem><para> the code and data </para></listitem>
|
||
|
<listitem><para> the import library </para></listitem>
|
||
|
</itemizedlist>
|
||
|
|
||
|
<para>The code and data are the parts you write - functions,
|
||
|
variables, etc. All these are merged together, like if you were
|
||
|
building one big object files, and put into the dll. They are not
|
||
|
put into your .exe at all.</para>
|
||
|
|
||
|
<para>The exports contains a list of functions and variables that the
|
||
|
dll makes available to other programs. Think of this as the list of
|
||
|
"global" symbols, the rest being hidden. Normally, you'd create this
|
||
|
list by hand with a text editor, but it's possible to do it
|
||
|
automatically from the list of functions in your code. The
|
||
|
<filename>dlltool</filename> program creates the exports section of
|
||
|
the dll from your text file of exported symbols.</para>
|
||
|
|
||
|
<para>The import library is a regular UNIX-like
|
||
|
<filename>.a</filename> library, but it only contains the tiny bit of
|
||
|
information needed to tell the OS how your program interacts with
|
||
|
("imports") the dll. This information is linked into your
|
||
|
<filename>.exe</filename>. This is also generated by
|
||
|
<filename>dlltool</filename>.</para>
|
||
|
|
||
|
<sect2 id="dll-build"><title>Building DLLs</title>
|
||
|
|
||
|
<para>OK, let's go through a simple example of how to build a dll.
|
||
|
For this example, we'll use a single file
|
||
|
<filename>myprog.c</filename> for the program
|
||
|
(<filename>myprog.exe</filename>) and a single file
|
||
|
<filename>mydll.c</filename> for the contents of the dll
|
||
|
(<filename>mydll.dll</filename>).</para>
|
||
|
|
||
|
<para>Now compile everything to objects:</para>
|
||
|
|
||
|
<screen>
|
||
|
gcc -c myprog.c
|
||
|
gcc -c mydll.c
|
||
|
</screen>
|
||
|
|
||
|
<para>Unfortunately, the process for building a dll is, well, convoluted.
|
||
|
You have to run five commands, like this:</para>
|
||
|
|
||
|
<screen>
|
||
|
gcc -s -Wl,--base-file,mydll.base -o mydll.dll mydll.o -Wl,-e,_mydll_init@12
|
||
|
dlltool --base-file mydll.base --def mydll.def --output-exp mydll.exp --dllname mydll.dll
|
||
|
gcc -s -Wl,--base-file,mydll.base,mydll.exp -o mydll.dll mydll.o -Wl,-e,_mydll_init@12
|
||
|
dlltool --base-file mydll.base --def mydll.def --output-exp mydll.exp --dllname mydll.dll
|
||
|
gcc -Wl,mydll.exp -o mydll.dll mydll.o -Wl,-e,_mydll_init@12
|
||
|
</screen>
|
||
|
|
||
|
<para>The extra steps give <filename>dlltool</filename> the
|
||
|
opportunity to generate the extra sections (exports and relocation)
|
||
|
that a dll needs. After this, you build the import library:</para>
|
||
|
|
||
|
<screen>
|
||
|
dlltool --def mydll.def --dllname mydll.dll --output-lib mydll.a
|
||
|
</screen>
|
||
|
|
||
|
<para>Now, when you build your program, you link against the import
|
||
|
library:</para>
|
||
|
|
||
|
<screen>
|
||
|
gcc -o myprog myprog.o mydll.a
|
||
|
</screen>
|
||
|
|
||
|
<para>Note that we linked with <command>-e _mydll_init@12</command>.
|
||
|
This tells the OS what the DLL's "entry point" is, and this is a
|
||
|
special function that coordinates bringing the dll to life withing the
|
||
|
OS. The minimum function looks like this:</para>
|
||
|
|
||
|
<screen>
|
||
|
#include <windows.h>
|
||
|
|
||
|
int WINAPI
|
||
|
mydll_init(HANDLE h, DWORD reason, void *foo)
|
||
|
{
|
||
|
return 1;
|
||
|
}
|
||
|
</screen>
|
||
|
|
||
|
</sect2>
|
||
|
|
||
|
<sect2 id="dll-link"><title>Linking Against DLLs</title>
|
||
|
|
||
|
<para>If you have an existing DLL already, you need to build a
|
||
|
Cygwin-compatible import library (The supplied ones should work, but
|
||
|
you might not have them) to link against. Unfortunately, there is not
|
||
|
yet any tool to do this automatically. However, you can get most of
|
||
|
the way by creating a .def file with these commands (you might need to
|
||
|
do this in <filename>bash</filename> for the quoting to work
|
||
|
correctly):</para>
|
||
|
|
||
|
<screen>
|
||
|
echo EXPORTS > foo.def
|
||
|
nm foo.dll | grep ' T _' | sed 's/.* T _//' >> foo.def
|
||
|
</screen>
|
||
|
|
||
|
<para>Note that this will only work if the DLL is not stripped.
|
||
|
Otherwise you will get an error message: "No symbols in
|
||
|
foo.dll".</para>
|
||
|
|
||
|
<para>Once you have the <filename>.def</filename> file, you can create
|
||
|
an import library from it like this:</para>
|
||
|
|
||
|
<screen>
|
||
|
dlltool --def foo.def --dllname foo.dll --output-lib foo.a
|
||
|
</screen>
|
||
|
|
||
|
</sect2>
|
||
|
|
||
|
</sect1>
|