📄 autobook_255.html
字号:
<DT>non Windows host<DD>It seems obvious, but we must also be careful not to contaminate thecode when it is compiled on a machine which doesn't need to jump throughthe DLL hoops.</DL><P>The changes to <TT>`hello.c'</TT> are no different to what would be requiredon a Unix machine. I have declared the <CODE>greet</CODE> variable toallow the caller to override the default greeting:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>#if HAVE_CONFIG_H# include <config.h>#endif#include <stdio.h>#include "hello.h"const char *greet = "Hello";inthello (const char *who){ printf("%s, %s!\n", greet, who); return 0;}</pre></td></tr></table></P><P>Again, since the DLL specific changes have been encapsulated in the<TT>`hello.h'</TT> file, enhancements to <TT>`main.c'</TT> are unsurprising too:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>#if HAVE_CONFIG_H# include <config.h>#endif#include "hello.h"intmain (int argc, const char *const argv[]){ if (argc > 1) { greet = argv[1]; } return hello("World");}</pre></td></tr></table></P><P>The final thing to be aware of is to be careful about ensuring that<SAMP>`LIBHELLO_DLL_IMPORT'</SAMP> is defined when we link an executable againstthe <TT>`libhello'</TT> DLL, but not defined if we link it against thestatic archive. It is impossible to automate this completely,particularly when the executable in question is from another package andis using the installed <TT>`hello.h'</TT> header. In that case it is theresponsibility of the author of that package to probe the system with<CODE>configure</CODE> to decide whether it will be linking with theDLL or the static archive, and defining <SAMP>`LIBHELLO_DLL_IMPORT'</SAMP>as appropriate.</P><P>Things are a little simpler when everything is under the control of asingle package, but even then it isn't quite possible to tell for surewhether Libtool is going to build a DLL or only a static library.For example, if some dependencies are dropped for being static, Libtoolmay disregard <SAMP>`-no-undefined'</SAMP> (see section <A HREF="autobook_88.html#SEC88">11.2.1 Creating Libtool Libraries with Automake</A>). One possible solution is:</P><P><OL><LI>Define a function in the library that invokes <SAMP>`return 1'</SAMP> from aDLL. Fortunately that's easy to accomplish thanks to<SAMP>`-DDLL_EXPORT'</SAMP>, in this case, by adding the following to<TT>`hello.c'</TT>:<P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>#if defined WIN32 && defined DLL_EXPORTcharlibhello_is_dll (void){ return 1;}#endif /* WIN32 && DLL_EXPORT */</pre></td></tr></table></P><P><LI>Link a program with the library, and check whether it is a DLL byseeing if the link succeeded.<P><LI>To get cross builds to work, you must, in the same vein, test whetherlinking a program which calls <SAMP>`libhello_is_dll'</SAMP> succeeds to tellwhether or not to define <SAMP>`LIBHELLO_DLL_IMPORT'</SAMP>.</OL><P>As an example of building the <TT>`hello'</TT> binary we can add thefollowing code to <TT>`configure.in'</TT>, just before the callto <SAMP>`AC_OUTPUT'</SAMP>:</P><P><TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre># ----------------------------------------------------------------------# Win32 objects need to tell the header whether they will be linking# with a dll or static archive in order that everything is imported# to the object in the same way that it was exported from the# archive (extern for static, __declspec(dllimport) for dlls)# ----------------------------------------------------------------------LIBHELLO_DLL_IMPORT=case "$host" in*-*-cygwin* | *-*-mingw* ) if test X"$enable_shared" = Xyes; then AC_TRY_LINK_FUNC([libhello_is_dll], [LIBHELLO_DLL_IMPORT=-DLIBHELLO_DLL_IMPORT]) fi ;;esacAC_SUBST(LIBHELLO_DLL_IMPORT)</FONT></pre></td></tr></table></P><P>And we must also arrange for the flag to be passed while compiling anyobjects which will end up in a binary which links with the dll. Forthis simple example, only <TT>`main.c'</TT> is affected, and we can add thefollowing rule to the end of <TT>`Makefile.am'</TT>:</P><P><TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>main.o: main.c $(COMPILE) @LIBHELLO_DLL_IMPORT@ -c main.c</FONT></pre></td></tr></table></P><P>In a more realistic project, there would probably be dozens of filesinvolved, in which case it would probably be easier to move them allto a separate subdirectory, and give them a <TT>`Makefile.am'</TT> of theirown which could include:</P><P><TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>CPPFLAGS = @LIBHELLO_DLL_IMPORT@</FONT></pre></td></tr></table></P><P>Now, lets put all this into practice, and check that it works:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>$ makecd . && aclocalcd . && automake --foreign Makefilecd . && autoconf...checking for gcc option to produce PIC ... -DDLL_EXPORTchecking if gcc PIC flag -DDLL_EXPORT works... yes...checking whether to build shared libraries... yes...gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -Wp,-MD,.deps/hello.pp \-c -DDLL_EXPORT -DPIC hello.c -o .libs/hello.logcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -Wp,-MD,.deps/hello.pp \-c hello.c -o hello.o >/dev/null 2>&1...gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -DLIBHELLO_DLL_IMPORT \-c main.c...gcc -g -O2 -o ./libs/hello main.o .libs/libimp-hello-0-0-0.a \-Wl,--rpath -Wl,/usr/local/libcreating hello...$ ./helloHello, World!$ ./hello HowdyHowdy, World!</pre></td></tr></table></P><P>The recipe also works if I use only the static archives:</P><P><TABLE width=100%><tr><td> </td><td class=example bgcolor=#6688aa><br><pre>$ make clean...$ ./configure --disable-shared...checking whether to build shared libraries... no...$ make...gcc -DHAVE_CONFIG_H -I. -I. -I. -f -O2 -Wp,-MD,.deps/hello.pp \-c hello.c -o hello.o...ar cru ./libs/libhello.a hello.o...gcc -DHAVE_CONFIG_H -I. -I. -I. -g -O2 -c main.c...gcc -g -O2 -o hello main.o ./.libs/libhello.a$ ./helloHello, World!$ ./hello "G'Day"G'day, World!</pre></td></tr></table></P><P>And just to be certain that I am really testing a new statically linkedexecutable:</P><P><TABLE><tr><td> </td><td class=smallexample><FONT SIZE=-1><pre>$ ldd ./hellohello.exe -> /tmp/hello.execygwin1.dll -> /usr/bin/cygwin1.dllkernel32.dll -> /WINNT/system32/kernel32.dllntdll.dll -> /WINNT/system32/ntdll.dlladvapi32.dll -> /WINNT/system32/advapi32.dlluser32.dll -> /WINNT/system32/user32.dllgdi32.dll -> /WINNT/system32/gdi32.dllrpcrt4.dll -> /WINNT/system32/rpcrt4.dll</FONT></pre></td></tr></table></P><P><A NAME="Runtime Loading of DLLs"></A></TR></TABLE><BR> <FONT SIZE="-1">This document was generatedby <I>Gary V. Vaughan</I> on <I>September, 12 2004</I>using <A HREF="http://www.mathematik.uni-kl.de/~obachman/Texi2html"><I>texi2html</I></A></BODY></HTML>
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -