142 lines
		
	
	
		
			4.7 KiB
		
	
	
	
		
			Plaintext
		
	
	
	
			
		
		
	
	
			142 lines
		
	
	
		
			4.7 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>This page gives only a few simple examples of gcc's DLL-building 
 | 
						|
capabilities. To begin an exploration of the many additional options,
 | 
						|
see the gcc documentation and website, currently at 
 | 
						|
<ulink url="http://gcc.gnu.org/">http://gcc.gnu.org/</ulink>
 | 
						|
</para>
 | 
						|
 | 
						|
<para>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>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>
 | 
						|
#include <stdio.h>
 | 
						|
 | 
						|
int
 | 
						|
hello()
 | 
						|
{
 | 
						|
  printf ("Hello World!\n");
 | 
						|
}  
 | 
						|
</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! To finish up the example, you can now link to the
 | 
						|
dll with a simple program:
 | 
						|
</para>
 | 
						|
 | 
						|
<screen>
 | 
						|
int 
 | 
						|
main ()
 | 
						|
{
 | 
						|
  hello ();
 | 
						|
}  
 | 
						|
</screen>
 | 
						|
 | 
						|
<para>
 | 
						|
Then link to your dll with a command like:
 | 
						|
</para>
 | 
						|
 | 
						|
<screen>gcc -o myprog myprog.ca -L./ -lmydll</screen>
 | 
						|
 | 
						|
<para>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_libs} \
 | 
						|
    -Wl,--no-whole-archive ${dependency_libs}</screen>
 | 
						|
 | 
						|
<para>
 | 
						|
The name of your library is <literal>${module}</literal>, prefixed with
 | 
						|
<literal>cyg</literal> for the DLL and <literal>lib</literal> for the
 | 
						|
import library. Cygwin DLLs use the <literal>cyg</literal> prefix to 
 | 
						|
differentiate them from native-Windows MinGW DLLs, see 
 | 
						|
<ulink url="http://mingw.org">the MinGW website</ulink> for more details.
 | 
						|
<literal>${old_libs}</literal> are all
 | 
						|
your object files, bundled together in static libs or single object
 | 
						|
files and the <literal>${dependency_libs}</literal> are import libs you 
 | 
						|
need to link against, e.g 
 | 
						|
<userinput>'-lpng -lz -L/usr/local/special -lmyspeciallib'</userinput>.
 | 
						|
</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.  If you have the source to compile
 | 
						|
the DLL, see <xref linkend="dll-build"></xref> for details on having 
 | 
						|
<filename>gcc</filename> build one for you.  If you do not have the
 | 
						|
source or a supplied working import library, 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>
 |