109 lines
3.9 KiB
Plaintext
109 lines
3.9 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>Fortunately, with the latest gcc and binutils the process for building a dll
|
|
is now pretty simple. Say you want to build this minimal function in mydll.c:</para>
|
|
|
|
<screen>int WINAPI
|
|
mydll_init(HANDLE h, DWORD reason, void *foo)
|
|
{
|
|
return 1;
|
|
}</screen>
|
|
|
|
<para>First compile mydll.c to object code:</para>
|
|
|
|
<screen>gcc -c mydll.c</screen>
|
|
|
|
<para>Then, tell gcc that it is building a shared library:</para>
|
|
|
|
<screen>gcc -shared -o mydll.dll mydll.o</screen>
|
|
|
|
<para>That's it! However, if you are building a dll as an export library,
|
|
you will probably want to use the complete syntax:</para>
|
|
|
|
<screen>gcc -shared -o cyg${module}.dll \
|
|
-Wl,--out-implib=lib${module}.dll.a \
|
|
-Wl,--export-all-symbols \
|
|
-Wl,--enable-auto-import \
|
|
-Wl,--whole-archive ${old_lib} \
|
|
-Wl,--no-whole-archive ${dependency_libs}</screen>
|
|
|
|
<para>Where ${module} is the name of your DLL, ${old_lib} are all
|
|
your object files, bundled together in static libs or single object
|
|
files and the ${dependency_libs} are import libs you need to
|
|
link against, e.g '-lpng -lz -L/usr/local/special -lmyspeciallib'.</para>
|
|
</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>
|