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>
 |