newlib-cygwin/winsup/doc/dll.sgml

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>