📄 autobook_165.html
字号:
<HTML><!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN"><!-- Created on September, 12 2004 by texi2html 1.64 --><!-- Written by: Lionel Cons <Lionel.Cons@cern.ch> (original author) Karl Berry <karl@freefriends.org> Olaf Bachmann <obachman@mathematik.uni-kl.de> and many others.Maintained by: Olaf Bachmann <obachman@mathematik.uni-kl.de>Send bugs and suggestions to <texi2html@mathematik.uni-kl.de> --><HEAD><TITLE>Autoconf, Automake, and Libtool: Introducing libltdl</TITLE><META NAME="description" CONTENT="Autoconf, Automake, and Libtool: Introducing libltdl"><META NAME="keywords" CONTENT="Autoconf, Automake, and Libtool: Introducing libltdl"><META NAME="resource-type" CONTENT="document"><META NAME="distribution" CONTENT="global"><META NAME="Generator" CONTENT="texi2html 1.64"><script language="Javascript"><!-- // Check the browser version. function checkVersion() { if (navigator.appVersion.charAt(0)>=3) return true; if (navigator.appVersion.charAt(0)>=4) return true; else return false; } if (checkVersion()) { homeon = new Image(); homeon.src = "homeon.png"; homeoff = new Image(); homeoff.src = "home.png"; tocon = new Image(); tocon.src = "tocon.png"; tocoff = new Image(); tocoff.src = "toc.png"; indexon = new Image(); indexon.src = "indexon.png"; indexoff = new Image(); indexoff.src = "index.png"; helpon = new Image(); helpon.src = "helpon.png"; helpoff = new Image(); helpoff.src = "help.png"; backon = new Image(); backon.src = "backon.png"; backoff = new Image(); backoff.src = "back.png"; forwardon = new Image(); forwardon.src = "forwardon.png"; forwardoff = new Image(); forwardoff.src = "forward.png"; prevon = new Image(); prevon.src = "prevon.png"; prevoff = new Image(); prevoff.src = "prev.png"; nexton = new Image(); nexton.src = "nexton.png"; nextoff = new Image(); nextoff.src = "next.png"; upon = new Image(); upon.src = "upon.png"; upoff = new Image(); upoff.src = "up.png"; } function img_act(imgName) { if (checkVersion()) { imgOn = eval(imgName + "on.src"); document [imgName].src = imgOn; } } function img_inact(imgName) { if (checkVersion()) { imgOff = eval(imgName + "off.src"); document [imgName].src = imgOff; } }// --></SCRIPT></HEAD><BODY LANG="EN" BGCOLOR="#FFFFFF" TEXT="#000000" LINK="#6688AA" VLINK="#336688" ALINK="#808080"><A NAME="SEC165"></A><TABLE BORDER=0 CELLPADDING=0 CELLSPACING=10><TR VALIGN="TOP"><TD ALIGN="MIDDLE" WIDTH=50 BGCOLOR="#e6e6e6"><TABLE CELLPADDING=1 CELLSPACING=1 BORDER=0><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_164.html#SEC164" onMouseover="img_act('prev')" onMouseout="img_inact('prev')"><IMG SRC="prev.png" BORDER="0" ALT="Back: Using GNU libltdl" ALIGN="MIDDLE" NAME="prev"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_166.html#SEC166" onMouseover="img_act('next')" onMouseout="img_inact('next')"><IMG SRC="next.png" BORDER="0" ALT="Forward: Using libltdl" ALIGN="MIDDLE" NAME="next"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"> <TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_164.html#SEC164" onMouseover="img_act('back')" onMouseout="img_inact('back')"><IMG SRC="back.png" BORDER="0" ALT="FastBack: Using GNU libltdl" ALIGN="MIDDLE" NAME="back"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_164.html#SEC164" onMouseover="img_act('up')" onMouseout="img_inact('up')"><IMG SRC="up.png" BORDER="0" ALT="Up: Using GNU libltdl" ALIGN="MIDDLE" NAME="up"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_178.html#SEC178" onMouseover="img_act('forward')" onMouseout="img_inact('forward')"><IMG SRC="forward.png" BORDER="0" ALT="FastForward: Advanced GNU Automake Usage" ALIGN="MIDDLE" NAME="forward"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook.html#SEC_Top" onMouseover="img_act('home')" onMouseout="img_inact('home')"><IMG SRC="home.png" BORDER="0" ALT="Top: Autoconf, Automake, and Libtool" ALIGN="MIDDLE" NAME="home"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_toc.html#SEC_Contents" onMouseover="img_act('toc')" onMouseout="img_inact('toc')"><IMG SRC="toc.png" BORDER="0" ALT="Contents: Table of Contents" ALIGN="MIDDLE" NAME="toc"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_285.html#SEC285" onMouseover="img_act('index')" onMouseout="img_inact('index')"><IMG SRC="index.png" BORDER="0" ALT="Index: Index" ALIGN="MIDDLE" NAME="index"></A></TD></TR><TR VALIGN="TOP" ALIGN="LEFT"><TD VALIGN="MIDDLE" ALIGN="LEFT"><A HREF="autobook_abt.html#SEC_About" onMouseover="img_act('help')" onMouseout="img_inact('help')"><IMG SRC="help.png" BORDER="0" ALT="About: About this document" ALIGN="MIDDLE" NAME="help"></A></TD></TR></TABLE></TD><TD ALIGN="LEFT"><H2> 18.1 Introducing libltdl </H2><!--docid::SEC165::--><P>Probably the best known and supported Unix run time linking API isthe <SAMP>`dlopen'</SAMP> interface, used by Solaris and GNU/Linux amongstothers, and discussed earlier in <A HREF="autobook_158.html#SEC158">17. Dynamic Loading</A>. libltdlis based on the <SAMP>`dlopen'</SAMP> API, with a few small differences andseveral enhancements.</P><P>The following libltdl API functions are declared in<TT>`ltdl.h'</TT>:</P><P><A NAME="IDX27"></A><DL><DT><U>Function:</U> lt_dlhandle <B>lt_dlopen</B> <I>(const char *<VAR>filename</VAR>)</I><DD>This function brings the code from a named module into the address spaceof the running program that calls it, and returns a handle which is usedby the other API functions. If <VAR>filename</VAR> is not an absolutepath, libltdl will search for it in directories named in the<SAMP>`LTDL_LIBRARY_PATH'</SAMP> environment variable, and then in the standardlibrary directories before giving up. It is safe to call thisfunction many times, libltdl will keep track of the number of callsmade, but will require the same number of calls to <SAMP>`lt_dlclose'</SAMP>to actually unload the module.</DL></P><P><A NAME="IDX28"></A><DL><DT><U>Function:</U> lt_ptr_t <B>lt_dlsym</B> <I>(lt_dlhandle <VAR>handle</VAR>, const char *<VAR>name</VAR>)</I><DD>Returns the address of the named symbol in the module which returned<VAR>handle</VAR> when it was <CODE>lt_dlopen</CODE>ed. You must cast the returnedaddress to a known type before using it.</DL></P><P><A NAME="IDX29"></A><DL><DT><U>Function:</U> int <B>lt_dlclose</B> <I>(lt_dlhandle <VAR>handle</VAR>)</I><DD>When you are finished with a particular module, it can be removed frommemory using this function.</DL></P><P><A NAME="IDX30"></A><DL><DT><U>Function:</U> const char * <B>lt_dlerror</B> <I>(void)</I><DD>If any of the libltdl API calls fail, this function returnsa string which describes the last error that occurred.</DL></P><P>In order to use these functions, you must <CODE>#include <ltdl.h></CODE> forthe function prototypes, and link with <SAMP>`-lltdl'</SAMP> to provide theAPI implementation. Assuming you link your application with<CODE>libtool</CODE>, and that you call the necessary macros from your<TT>`configure.in'</TT> (see section <A HREF="autobook_166.html#SEC166">18.2 Using libltdl</A>), then any host specificdependent libraries (for example, <TT>`libdl'</TT> on GNU/Linux) willautomatically be added to the final link line by <CODE>libtool</CODE>.</P><P>You don't limit yourself to using only Libtool compiled modules when youuse libltdl. By writing the module loader carefully, it will be able toload native modules too--although you will not be able to preloadnon-Libtool modules (see section <A HREF="autobook_173.html#SEC173">18.4 dlpreopen Loading</A>. The loader in<A HREF="autobook_169.html#SEC169">Module Loader</A> is written in this way. Itis useful to be able to load modules flexibly like this, because youdon't tie your users into using Libtool for any modules they write. </P><P>Compare the descriptions of the functions above with the APIdescribed in <A HREF="autobook_160.html#SEC160">17.2 Module Access Functions</A>. You will notice that theyare very similar.</P><P><A NAME="IDX31"></A><BLOCKQUOTE>Back-linking is the process of resolving any remaining symbols byreferencing back into the application that loads the library at runtime-- a mechanism implemented on almost all modern Unices.<P>For instance, your main application may provide some utility function,<SAMP>`my_function'</SAMP>, which you want a module to have access to. There aretwo ways to do that:</P><P><UL><LI>You could use Libtool to link your application, using the<SAMP>`-export-dynamic'</SAMP> option to ensure that the global applicationsymbols are available to modules. When libltdl loads a module into anapplication compiled like this, it will <EM>back-link</EM> symbols from theapplication to resolve any otherwise undefined symbols in a module.When the module is <SAMP>`ltdlopen'</SAMP>ed, libltdl will arrange forcalls to <SAMP>`my_function'</SAMP> in the module, to execute the<SAMP>`my_function'</SAMP> implementation in the application.<P>If you have need of this functionality, relying on back-linking is thesimplest way to achieve it. Unfortunately, this simplicity is at theexpense of portability: some platforms have no support forback-linking at all, and others will not allow a module to be createdwith unresolved symbols. Never-the-less, libltdl allows you to do thisif you want to.</P><P><LI>You could split the code that implements the symbols you need to sharewith modules into a separate library. This library would then be usedto resolve the symbols you wish to share, by linking it into modules andapplication alike. The definition of <SAMP>`my_function'</SAMP> would becompiled separately into a library, <TT>`libmy_function.la'</TT>.References to <SAMP>`my_function'</SAMP> from the application would be resolvedby linking it with <TT>`libmy_function.la'</TT>, and the library would beinstalled so that modules which need to call <SAMP>`my_function'</SAMP> would beable to resolve the symbol by linking with <SAMP>`-lmy_function'</SAMP>.<P>This method requires support for neither back-linking nor unresolvedlink time symbols from the host platform. The disadvantage is that whenyou realise you need this functionality, it may be quite complicated toextract the shared functionality from the application to be compiled ina stand alone library.</UL></BLOCKQUOTE><P>On those platforms which support <EM>back-linking</EM>, libltdl canbe configured to resolve external symbol references in a dynamic modulewith any global symbols already present in the main application.This has two implications for the libltdl API:</P><P><UL><LI>There is no need to pass <SAMP>`RTLD_GLOBAL'</SAMP> (or equivalent) to<CODE>lt_dlopen</CODE> as might be necessary with the native module loadingAPI.<P><LI>You should be aware that your application will not work on someplatforms--most notably, Windows and AIX---if you rely ona back-linking.</UL><P>Similarly, there is no need to specify whether the module should beintegrated into the application core before <CODE>lt_dlopen</CODE> returns, orelse when the symbols it provides are first referenced. libltdlwill use <EM>lazy loading</EM> if it is supported, since this is a slightperformance enhancement, or else fall back to loading everythingimmediately. Between this feature and the support of back-linking,there is no need to pass flags into <CODE>lt_dlopen</CODE> as there is withmost native <CODE>dlopen</CODE> APIs.</P><P>There are a couple of other important API functions which you willneed when using libltdl:</P><P><A NAME="IDX32"></A><DL><DT><U>Function:</U> int <B>lt_dlinit</B> <I>(void)</I><DD>You must call this function to initialise libltdl before callingany of the other libltdl API functions. It is safe to call thisfunction many times, libltdl will keep track of the number of callsmade, but will require the same number of calls to <SAMP>`lt_dlexit'</SAMP>to actually recycle the library resources. If you don't call<SAMP>`lt_dlinit'</SAMP> before any other API call, the other calls,including <SAMP>`lt_dlerror'</SAMP>, will return their respective failure codes(<SAMP>`NULL'</SAMP> or <SAMP>`1'</SAMP>, as appropriate).</DL></P><P><A NAME="IDX33"></A><DL><DT><U>Function:</U> int <B>lt_dlexit</B> <I>(void)</I><DD>When you are done with libltdl and all dynamic modules have beenunloaded you can call this function to finalise the library, and recycleits resources. If you forget to unload any modules, the call to<SAMP>`lt_dlexit'</SAMP> will <SAMP>`lt_dlclose'</SAMP> them for you.</DL></P><P>Another useful departure that the libltdl API makes from avanilla <CODE>dlopen</CODE> implementation is that it also will work correctlywith old K&R C compilers, by virtue of not relying on <SAMP>`void *'</SAMP>pointers. libltdl uses <CODE>lt_dlhandle</CODE>s to pass references toloaded modules, and this also improves ANSI C compiler's typechecking compared to the untyped addresses typically used by native<CODE>dlopen</CODE> APIs.</P><P><A NAME="Using libltdl"></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 + -