summaryrefslogtreecommitdiffstats
path: root/doc/html/ksquirrel-libs-olibs2.html
diff options
context:
space:
mode:
authortpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
committertpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da>2010-02-24 17:43:19 +0000
commit0292059f4a16434600564cfa3f0ad2309a508a54 (patch)
treed95953cd53011917c4df679b96aedca39401b54f /doc/html/ksquirrel-libs-olibs2.html
downloadlibksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.tar.gz
libksquirrel-0292059f4a16434600564cfa3f0ad2309a508a54.zip
Added libksquirrel for KDE3
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/libraries/libksquirrel@1095624 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'doc/html/ksquirrel-libs-olibs2.html')
-rw-r--r--doc/html/ksquirrel-libs-olibs2.html1620
1 files changed, 1620 insertions, 0 deletions
diff --git a/doc/html/ksquirrel-libs-olibs2.html b/doc/html/ksquirrel-libs-olibs2.html
new file mode 100644
index 0000000..710df8a
--- /dev/null
+++ b/doc/html/ksquirrel-libs-olibs2.html
@@ -0,0 +1,1620 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
+<html>
+<head>
+ <title>KSquirrel: development</title>
+
+ <meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+ <meta name='Author' content='Baryshev Dmitry/Krasu'>
+
+ <link rel="stylesheet" href="styles.css" type="text/css">
+</head>
+<body>
+
+<DIV
+CLASS="ARTICLE"
+><DIV
+CLASS="TITLEPAGE"
+><H1
+CLASS="title"
+><A
+NAME="AEN2"
+></A
+>C++ dlopen mini HOWTO</H1
+><H3
+CLASS="author"
+><A
+NAME="AEN4"
+>Aaron Isotton</A
+></H3
+><DIV
+CLASS="affiliation"
+><DIV
+CLASS="address"
+><P
+CLASS="address"
+><TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:[email protected]"
+>&#62;</TT
+></P
+></DIV
+></DIV
+><P
+CLASS="pubdate"
+>2003-08-12<BR></P
+><DIV
+CLASS="revhistory"
+><TABLE
+WIDTH="100%"
+BORDER="0"
+><TR
+><TH
+ALIGN="LEFT"
+VALIGN="TOP"
+COLSPAN="3"
+><B
+>Revision History</B
+></TH
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.03</TD
+><TD
+ALIGN="LEFT"
+>2003-08-12</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Added reference to the GLib Dynamic Module
+ Loader. Thanks to G. V. Sriraam for the pointer.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.02</TD
+><TD
+ALIGN="LEFT"
+>2002-12-08</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Added FAQ. Minor changes</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.01</TD
+><TD
+ALIGN="LEFT"
+>2002-06-30</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Updated virtual destructor explanation. Minor changes.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 1.00</TD
+><TD
+ALIGN="LEFT"
+>2002-06-19</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Moved copyright and license section to the
+ beginning. Added terms section. Minor changes.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 0.97</TD
+><TD
+ALIGN="LEFT"
+>2002-06-19</TD
+><TD
+ALIGN="LEFT"
+>Revised by: JYG</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Entered minor grammar and sentence level changes.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 0.96</TD
+><TD
+ALIGN="LEFT"
+>2002-06-12</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Added bibliography. Corrected explanation of extern
+ functions and variables.</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+>Revision 0.95</TD
+><TD
+ALIGN="LEFT"
+>2002-06-11</TD
+><TD
+ALIGN="LEFT"
+>Revised by: AI</TD
+></TR
+><TR
+><TD
+ALIGN="LEFT"
+COLSPAN="3"
+>Minor improvements.</TD
+></TR
+></TABLE
+></DIV
+><DIV
+><DIV
+CLASS="abstract"
+><A
+NAME="AEN47"
+></A
+><P
+></P
+><P
+>How to dynamically load C++ functions and classes using
+ the <TT
+CLASS="function"
+>dlopen</TT
+> API.</P
+><P
+></P
+></DIV
+></DIV
+><HR></DIV
+><DIV
+CLASS="TOC"
+><DL
+><DT
+><B
+>Table of Contents</B
+></DT
+><DT
+>1. <A
+HREF="#intro"
+>Introduction</A
+></DT
+><DD
+><DL
+><DT
+>1.1. <A
+HREF="#copyright"
+>Copyright and License</A
+></DT
+><DT
+>1.2. <A
+HREF="#disclaimer"
+>Disclaimer</A
+></DT
+><DT
+>1.3. <A
+HREF="#credits"
+>Credits / Contributors</A
+></DT
+><DT
+>1.4. <A
+HREF="#feedback"
+>Feedback</A
+></DT
+><DT
+>1.5. <A
+HREF="#AEN85"
+>Terms Used in this Document</A
+></DT
+></DL
+></DD
+><DT
+>2. <A
+HREF="#theproblem"
+>The Problem</A
+></DT
+><DD
+><DL
+><DT
+>2.1. <A
+HREF="#mangling"
+>Name Mangling</A
+></DT
+><DT
+>2.2. <A
+HREF="#AEN131"
+>Classes</A
+></DT
+></DL
+></DD
+><DT
+>3. <A
+HREF="#thesolution"
+>The Solution</A
+></DT
+><DD
+><DL
+><DT
+>3.1. <A
+HREF="#externC"
+><TT
+CLASS="literal"
+>extern "C"</TT
+></A
+></DT
+><DT
+>3.2. <A
+HREF="#loadingfunctions"
+>Loading Functions</A
+></DT
+><DT
+>3.3. <A
+HREF="#loadingclasses"
+>Loading Classes</A
+></DT
+></DL
+></DD
+><DT
+>4. <A
+HREF="#faq"
+>Frequently Asked Questions</A
+></DT
+><DT
+>5. <A
+HREF="#seealso"
+>See Also</A
+></DT
+><DT
+><A
+HREF="#AEN295"
+>Bibliography</A
+></DT
+></DL
+></DIV
+><DIV
+CLASS="section"
+><H1
+CLASS="section"
+><A
+NAME="intro"
+></A
+>1. Introduction</H1
+><P
+>&#13; A question which frequently arises among Unix C++ programmers is
+ how to load C++ functions and classes dynamically using the
+ <TT
+CLASS="function"
+>dlopen</TT
+> API.
+ </P
+><P
+>In fact, that is not always simple and needs some
+ explanation. That's what this mini HOWTO does.</P
+><P
+>An average understanding of the <SPAN
+CLASS="systemitem"
+>C</SPAN
+>
+ and <SPAN
+CLASS="systemitem"
+>C++</SPAN
+> programming language and of the
+ <TT
+CLASS="function"
+>dlopen</TT
+> API is necessary to understand this
+ document.</P
+><P
+>This HOWTO's master location is <A
+HREF="http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/"
+TARGET="_top"
+>http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/</A
+>.</P
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="copyright"
+></A
+>1.1. Copyright and License</H2
+><P
+>&#13; This document, <EM
+>C++ dlopen mini HOWTO</EM
+>, is
+ copyrighted (c) 2002 by <EM
+>Aaron Isotton</EM
+>.
+ Permission is granted to copy, distribute and/or modify this
+ document under the terms of the GNU Free Documentation
+ License, Version 1.1 or any later version published by the
+ Free Software Foundation; with no Invariant Sections, with no
+ Front-Cover Texts, and with no Back-Cover Texts.
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="disclaimer"
+></A
+>1.2. Disclaimer</H2
+><P
+>&#13; No liability for the contents of this document can be
+ accepted. Use the concepts, examples and information at your
+ own risk. There may be errors and inaccuracies, that could be
+ damaging to your system. Proceed with caution, and although
+ this is highly unlikely, the author(s) do not take any
+ responsibility.
+ </P
+><P
+>&#13; All copyrights are held by their by their respective owners,
+ unless specifically noted otherwise. Use of a term in this
+ document should not be regarded as affecting the validity of
+ any trademark or service mark. Naming of particular products
+ or brands should not be seen as endorsements.
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="credits"
+></A
+>1.3. Credits / Contributors</H2
+><P
+>&#13; In this document, I have the pleasure of acknowledging (in
+ alphabetic order):
+ </P
+><P
+></P
+><UL
+><LI
+><P
+>Joy Y Goodreau <TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:joyg (at) us.ibm.com"
+>joyg (at) us.ibm.com</A
+>&#62;</TT
+> for
+ her editing.</P
+></LI
+><LI
+><P
+>D. Stimitis <TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:stimitis (at) idcomm.com"
+>stimitis (at) idcomm.com</A
+>&#62;</TT
+>
+ for pointing out a few issues with the formatting and the
+ name mangling, as well as pointing out a few subtleties of
+ <TT
+CLASS="literal"
+>extern "C"</TT
+>.</P
+></LI
+></UL
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="feedback"
+></A
+>1.4. Feedback</H2
+><P
+>&#13; Feedback is most certainly welcome for this document. Send
+ your additions, comments and criticisms to the following email
+ address: <TT
+CLASS="email"
+>&#60;<A
+HREF="mailto:[email protected]"
+>&#62;</TT
+>.
+ </P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="AEN85"
+></A
+>1.5. Terms Used in this Document</H2
+><P
+></P
+><DIV
+CLASS="variablelist"
+><DL
+><DT
+><TT
+CLASS="function"
+>dlopen</TT
+> API</DT
+><DD
+><P
+>The <TT
+CLASS="function"
+>dlclose</TT
+>,
+ <TT
+CLASS="function"
+>dlerror</TT
+>,
+ <TT
+CLASS="function"
+>dlopen</TT
+> and
+ <TT
+CLASS="function"
+>dlsym</TT
+> functions as described in the
+ <TT
+CLASS="literal"
+>dlopen(3)</TT
+> man page.</P
+><P
+>Notice that we use
+ <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="function"
+>dlopen</TT
+>"</SPAN
+> to refer to
+ the individual <TT
+CLASS="function"
+>dlopen</TT
+>
+ <EM
+>function</EM
+>, and
+ <SPAN
+CLASS="QUOTE"
+>"<TT
+CLASS="function"
+>dlopen</TT
+> API"</SPAN
+> to refer
+ to the <EM
+>entire API</EM
+>.</P
+></DD
+></DL
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="theproblem"
+></A
+>2. The Problem</H1
+><P
+>At some time you might have to load a library (and use its
+ functions) at runtime; this happens most often when you are
+ writing some kind of plug-in or module architecture for your
+ program.</P
+><P
+>In the C language, loading a library is very simple (calling
+ <TT
+CLASS="function"
+>dlopen</TT
+>, <TT
+CLASS="function"
+>dlsym</TT
+> and
+ <TT
+CLASS="function"
+>dlclose</TT
+> is enough), with C++ this is a bit
+ more complicated. The difficulties of loading a C++ library
+ dynamically are partially due to <A
+HREF="#mangling"
+>name
+ mangling</A
+>, and partially due to the fact that the
+ <TT
+CLASS="function"
+>dlopen</TT
+> API was written with C in mind, thus
+ not offering a suitable way to load classes.</P
+><P
+>Before explaining how to load libraries in C++, let's better
+ analyze the problem by looking at name mangling in more
+ detail. I recommend you read the explanation of name mangling,
+ even if you're not interested in it because it will help you
+ understanding why problems occur and how to solve them.</P
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="mangling"
+></A
+>2.1. Name Mangling</H2
+><P
+>In every C++ program (or library, or object file), all
+ non-static functions are represented in the binary file as
+ <EM
+>symbols</EM
+>. These symbols are special text
+ strings that uniquely identify a function in the program,
+ library, or object file.</P
+><P
+>In C, the symbol name is the same as the function name:
+ the symbol of <TT
+CLASS="function"
+>strcpy</TT
+> will be
+ <TT
+CLASS="computeroutput"
+>strcpy</TT
+>, and so on. This is
+ possible because in C no two non-static functions can have the
+ same name.</P
+><P
+>Because C++ allows overloading (different functions with
+ the same name but different arguments) and has many features C
+ does not &#8212; like classes, member functions, exception
+ specifications &#8212; it is not possible to simply use the
+ function name as the symbol name. To solve that, C++ uses
+ so-called <EM
+>name mangling</EM
+>, which transforms
+ the function name and all the necessary information (like the
+ number and size of the arguments) into some weird-looking
+ string which only the compiler knows about. The mangled name
+ of <TT
+CLASS="function"
+>foo</TT
+> might look like
+ <TT
+CLASS="computeroutput"
+>foo@4%6^</TT
+>, for example. Or it
+ might not even contain the word <SPAN
+CLASS="QUOTE"
+>"foo"</SPAN
+>.</P
+><P
+> One of the problems with name mangling is that the C++
+ standard (currently [<SPAN
+CLASS="citation"
+>ISO14882</SPAN
+>]) does not
+ define how names have to be mangled; thus every compiler
+ mangles names in its own way. Some compilers even change their
+ name mangling algorithm between different versions (notably
+ g++ 2.x and 3.x). Even if you worked out how your particular
+ compiler mangles names (and would thus be able to load
+ functions via <TT
+CLASS="function"
+>dlsym</TT
+>), this would most
+ probably work with your compiler only, and might already be
+ broken with the next version.</P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="AEN131"
+></A
+>2.2. Classes</H2
+><P
+>Another problem with the <TT
+CLASS="function"
+>dlopen</TT
+> API
+ is the fact that it only supports loading
+ <EM
+>functions</EM
+>. But in C++ a library often
+ exposes a class which you would like to use in your
+ program. Obviously, to use that class you need to create an
+ instance of it, but that cannot be easily done.</P
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="thesolution"
+></A
+>3. The Solution</H1
+><DIV
+CLASS="section"
+><H2
+CLASS="section"
+><A
+NAME="externC"
+></A
+>3.1. <TT
+CLASS="literal"
+>extern "C"</TT
+></H2
+><P
+>C++ has a special keyword to declare a function with C
+ bindings: <TT
+CLASS="literal"
+>extern "C"</TT
+>. A function declared
+ as <TT
+CLASS="literal"
+>extern "C"</TT
+> uses the function name as
+ symbol name, just as a C function. For that reason, only
+ non-member functions can be declared as <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>, and they cannot be overloaded.</P
+><P
+>Although there are severe limitations, <TT
+CLASS="literal"
+>extern
+ "C"</TT
+> functions are very useful because they can be
+ dynamically loaded using <TT
+CLASS="function"
+>dlopen</TT
+> just like
+ a C function.</P
+><P
+>This does <EM
+>not</EM
+> mean that functions
+ qualified as <TT
+CLASS="literal"
+>extern "C"</TT
+> cannot contain C++
+ code. Such a function is a full-featured C++ function which
+ can use C++ features and take any type of argument.</P
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="loadingfunctions"
+></A
+>3.2. Loading Functions</H2
+><P
+>In C++ functions are loaded just like in C, with
+ <TT
+CLASS="function"
+>dlsym</TT
+>. The functions you want to load
+ must be qualified as <TT
+CLASS="literal"
+>extern "C"</TT
+> to avoid
+ the symbol name being mangled.</P
+><DIV
+CLASS="example"
+><A
+NAME="AEN156"
+></A
+><P
+><B
+>Example 1. Loading a Function</B
+></P
+><P
+>main.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include &#60;iostream&#62;
+#include &#60;dlfcn.h&#62;
+
+
+int main() {
+ using std::cout;
+ using std::cerr;
+
+ cout &#60;&#60; "C++ dlopen demo\n\n";
+
+ // open the library
+ cout &#60;&#60; "Opening hello.so...\n";
+ void* handle = dlopen("./hello.so", RTLD_LAZY);
+
+ if (!handle) {
+ cerr &#60;&#60; "Cannot open library: " &#60;&#60; dlerror() &#60;&#60; '\n';
+ return 1;
+ }
+
+ // load the symbol
+ cout &#60;&#60; "Loading symbol hello...\n";
+ typedef void (*hello_t)();
+ hello_t hello = (hello_t) dlsym(handle, "hello");
+ if (!hello) {
+ cerr &#60;&#60; "Cannot load symbol 'hello': " &#60;&#60; dlerror() &#60;&#60;
+ '\n';
+ dlclose(handle);
+ return 1;
+ }
+
+ // use it to do the calculation
+ cout &#60;&#60; "Calling hello...\n";
+ hello();
+
+ // close the library
+ cout &#60;&#60; "Closing library...\n";
+ dlclose(handle);
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+>hello.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include &#60;iostream&#62;
+
+extern "C" void hello() {
+ std::cout &#60;&#60; "hello" &#60;&#60; '\n';
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>The function <TT
+CLASS="function"
+>hello</TT
+> is defined in
+ <TT
+CLASS="filename"
+>hello.cpp</TT
+>as <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>; it is loaded in <TT
+CLASS="filename"
+>main.cpp</TT
+>
+ with the <TT
+CLASS="function"
+>dlsym</TT
+> call. The function must be
+ qualified as <TT
+CLASS="literal"
+>extern "C"</TT
+> because otherwise
+ we wouldn't know its symbol name.</P
+><DIV
+CLASS="warning"
+><P
+></P
+><TABLE
+CLASS="warning"
+WIDTH="100%"
+BORDER="0"
+><TR
+><TD
+WIDTH="25"
+ALIGN="CENTER"
+VALIGN="TOP"
+><IMG
+SRC="../images/warning.gif"
+HSPACE="5"
+ALT="Warning"></TD
+><TD
+ALIGN="LEFT"
+VALIGN="TOP"
+><P
+>There are two different forms of the
+ <TT
+CLASS="literal"
+>extern "C"</TT
+> declaration: <TT
+CLASS="literal"
+>extern
+ "C"</TT
+> as used above, and <TT
+CLASS="literal"
+>extern "C" {
+ &#8230; }</TT
+> with the declarations between the
+ braces. The first (inline) form is a declaration with extern
+ linkage and with C language linkage; the second only affects
+ language linkage. The following two declarations are thus
+ equivalent:
+
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN174"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" int foo;
+extern "C" void bar();
+ </PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+ and
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN176"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" {
+ extern int foo;
+ extern void bar();
+ }</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+
+ As there is no difference between an
+ <TT
+CLASS="literal"
+>extern</TT
+> and a
+ non-<TT
+CLASS="literal"
+>extern</TT
+> <EM
+>function</EM
+>
+ declaration, this is no problem as long as you are not
+ declaring any variables. If you declare
+ <EM
+>variables</EM
+>, keep in mind that
+
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN182"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" int foo;</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+ and
+ <DIV
+CLASS="informalexample"
+><A
+NAME="AEN184"
+></A
+><P
+></P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>extern "C" {
+ int foo;
+}</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+></P
+></DIV
+>
+
+ are <EM
+>not</EM
+> the same thing.</P
+><P
+>For further clarifications, refer to
+ [<SPAN
+CLASS="citation"
+>ISO14882</SPAN
+>], 7.5, with special attention
+ to paragraph 7, or to [<SPAN
+CLASS="citation"
+>STR2000</SPAN
+>],
+ paragraph 9.2.4.</P
+><P
+>Before doing fancy things with extern variables, peruse
+ the documents listed in the <A
+HREF="#seealso"
+>see
+ also</A
+> section.</P
+></TD
+></TR
+></TABLE
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H2
+CLASS="section"
+><A
+NAME="loadingclasses"
+></A
+>3.3. Loading Classes</H2
+><P
+>Loading classes is a bit more difficult because we need
+ an <EM
+>instance</EM
+> of a class, not just a
+ pointer to a function.</P
+><P
+>We cannot create the instance of the class using
+ <TT
+CLASS="literal"
+>new</TT
+> because the class is not defined in the
+ executable, and because (under some circumstances) we don't
+ even know its name.</P
+><P
+>The solution is achieved through polymorphism. We define a
+ base, <EM
+>interface</EM
+> class with virtual
+ members <EM
+>in the executable</EM
+>, and a derived,
+ <EM
+>implementation</EM
+> class <EM
+>in the
+ module</EM
+>. Generally the interface class is
+ abstract (a class is abstract if it has pure virtual
+ functions).</P
+><P
+>As dynamic loading of classes is generally used for
+ plug-ins &#8212; which must expose a clearly defined interface
+ &#8212; we would have had to define an interface and derived
+ implementation classes anyway.</P
+><P
+>Next, while still in the module, we define two additional helper
+ functions, known as <EM
+>class factory
+ functions</EM
+>. One of these functions creates an instance of the
+ class and returns a pointer to it. The other function takes a
+ pointer to a class created by the factory and destroys
+ it. These two functions are qualified as <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>.</P
+><P
+>To use the class from the module, load the two factory
+ functions using <TT
+CLASS="function"
+>dlsym</TT
+> just <A
+HREF="#loadingfunctions"
+>as we loaded the the hello
+ function</A
+>; then, we can create and destroy as many
+ instances as we wish.</P
+><DIV
+CLASS="example"
+><A
+NAME="AEN210"
+></A
+><P
+><B
+>Example 2. Loading a Class</B
+></P
+><P
+>Here we use a generic <TT
+CLASS="classname"
+>polygon</TT
+>
+ class as interface and the derived class
+ <TT
+CLASS="classname"
+>triangle</TT
+> as implementation.</P
+><P
+>main.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include "polygon.hpp"
+#include &#60;iostream&#62;
+#include &#60;dlfcn.h&#62;
+
+int main() {
+ using std::cout;
+ using std::cerr;
+
+ // load the triangle library
+ void* triangle = dlopen("./triangle.so", RTLD_LAZY);
+ if (!triangle) {
+ cerr &#60;&#60; "Cannot load library: " &#60;&#60; dlerror() &#60;&#60; '\n';
+ return 1;
+ }
+
+ // load the symbols
+ create_t* create_triangle = (create_t*) dlsym(triangle, "create");
+ destroy_t* destroy_triangle = (destroy_t*) dlsym(triangle, "destroy");
+ if (!create_triangle || !destroy_triangle) {
+ cerr &#60;&#60; "Cannot load symbols: " &#60;&#60; dlerror() &#60;&#60; '\n';
+ return 1;
+ }
+
+ // create an instance of the class
+ polygon* poly = create_triangle();
+
+ // use the class
+ poly-&#62;set_side_length(7);
+ cout &#60;&#60; "The area is: " &#60;&#60; poly-&#62;area() &#60;&#60; '\n';
+
+ // destroy the class
+ destroy_triangle(poly);
+
+ // unload the triangle library
+ dlclose(triangle);
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+>polygon.hpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#ifndef POLYGON_HPP
+#define POLYGON_HPP
+
+class polygon {
+protected:
+ double side_length_;
+
+public:
+ polygon()
+ : side_length_(0) {}
+
+ void set_side_length(double side_length) {
+ side_length_ = side_length;
+ }
+
+ virtual double area() const = 0;
+};
+
+// the types of the class factories
+typedef polygon* create_t();
+typedef void destroy_t(polygon*);
+
+#endif
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+><P
+>triangle.cpp:</P
+><TABLE
+BORDER="0"
+BGCOLOR="#E0E0E0"
+WIDTH="100%"
+><TR
+><TD
+><FONT
+COLOR="#000000"
+><PRE
+CLASS="programlisting"
+>#include "polygon.hpp"
+#include &#60;cmath&#62;
+
+class triangle : public polygon {
+public:
+ virtual double area() const {
+ return side_length_ * side_length_ * sqrt(3) / 2;
+ }
+};
+
+
+// the class factories
+
+extern "C" polygon* create() {
+ return new triangle;
+}
+
+extern "C" void destroy(polygon* p) {
+ delete p;
+}
+</PRE
+></FONT
+></TD
+></TR
+></TABLE
+></DIV
+><P
+>There are a few things to note when loading classes:</P
+><P
+></P
+><UL
+><LI
+><P
+>You must provide <EM
+>both</EM
+> a creation
+ and a destruction function; you must
+ <EM
+>not</EM
+> destroy the instances using
+ <TT
+CLASS="literal"
+>delete</TT
+> from inside the executable, but
+ always pass it back to the module. This is due to the fact
+ that in C++ the operators <TT
+CLASS="literal"
+>new</TT
+> and
+ <TT
+CLASS="literal"
+>delete</TT
+> may be overloaded; this would
+ cause a non-matching <TT
+CLASS="literal"
+>new</TT
+> and
+ <TT
+CLASS="literal"
+>delete</TT
+> to be called, which could cause
+ anything from nothing to memory leaks and segmentation
+ faults. The same is true if different standard libraries
+ are used to link the module and the executable.</P
+></LI
+><LI
+><P
+>The destructor of the interface class should be
+ virtual in any case. There <EM
+>might</EM
+> be
+ very rare cases where that would not be necessary, but it
+ is not worth the risk, because the additional overhead can
+ generally be ignored.</P
+><P
+>If your base class needs no destructor, define an
+ empty (and <TT
+CLASS="literal"
+>virtual</TT
+>) one anyway;
+ otherwise you <EM
+>will have problems</EM
+>
+ sooner or later; I can guarantee you that. You can read
+ more about this problem in the comp.lang.c++ FAQ at <A
+HREF="http://www.parashift.com/c++-faq-lite/"
+TARGET="_top"
+>http://www.parashift.com/c++-faq-lite/</A
+>, in
+ section 20.</P
+></LI
+></UL
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="faq"
+></A
+>4. Frequently Asked Questions</H1
+><DIV
+CLASS="qandaset"
+><DL
+><DT
+>4.1. <A
+HREF="#AEN243"
+>I'm using Windows and I can't find the
+ <TT
+CLASS="filename"
+>dlfcn.h</TT
+> header file on my PC! What's
+ the problem?</A
+></DT
+><DT
+>4.2. <A
+HREF="#AEN257"
+>Is there some kind of <TT
+CLASS="function"
+>dlopen</TT
+>-compatible
+ wrapper for the Windows <TT
+CLASS="function"
+>LoadLibrary</TT
+>
+ API?</A
+></DT
+></DL
+><DIV
+CLASS="qandaentry"
+><DIV
+CLASS="question"
+><P
+><A
+NAME="AEN243"
+></A
+><B
+>4.1. </B
+>I'm using Windows and I can't find the
+ <TT
+CLASS="filename"
+>dlfcn.h</TT
+> header file on my PC! What's
+ the problem?</P
+></DIV
+><DIV
+CLASS="answer"
+><P
+><B
+> </B
+>The problem is, as usual, Windows. There is no
+ <TT
+CLASS="filename"
+>dlfcn.h</TT
+> header on Windows,and there is
+ no <TT
+CLASS="function"
+>dlopen</TT
+> API. There is a similar API
+ around the <TT
+CLASS="function"
+>LoadLibrary</TT
+> function, and
+ most of what is written here applies to it, too.
+ Alternatively, you can use libltdl (included in libtool) to
+ <SPAN
+CLASS="QUOTE"
+>"emulate"</SPAN
+> <TT
+CLASS="function"
+>dlopen</TT
+> on a
+ variety of platforms.</P
+><P
+>You should also read section 4, <SPAN
+CLASS="QUOTE"
+>"Dynamically
+ Loaded (DL) Libraries"</SPAN
+>, of the <A
+HREF="http://www.dwheeler.com/program-library"
+TARGET="_top"
+>Program Library
+ HOWTO</A
+> for more techniques to load libraries and
+ create classes independently of your platform.</P
+></DIV
+></DIV
+><DIV
+CLASS="qandaentry"
+><DIV
+CLASS="question"
+><P
+><A
+NAME="AEN257"
+></A
+><B
+>4.2. </B
+>Is there some kind of <TT
+CLASS="function"
+>dlopen</TT
+>-compatible
+ wrapper for the Windows <TT
+CLASS="function"
+>LoadLibrary</TT
+>
+ API?</P
+></DIV
+><DIV
+CLASS="answer"
+><P
+><B
+> </B
+>I don't know of any, and I don't think there'll ever be one
+ supporting all of <TT
+CLASS="function"
+>dlopen</TT
+>'s options.</P
+><P
+>There are alternatives though: libtltdl (a part of libtool),
+ which wraps a variety of different dynamic loading APIs, among
+ others <TT
+CLASS="function"
+>dlopen</TT
+> and
+ <TT
+CLASS="function"
+>LoadLibrary</TT
+>. Another one is the <A
+HREF="http://developer.gnome.org/doc/API/glib/glib-dynamic-loading-of-modules.html"
+TARGET="_top"
+>Dynamic
+ Module Loading functionality of GLib</A
+>. You can use one
+ of these to ensure better possible cross-platform compatibility.
+ I've never used any of them, so I can't tell you how stable they
+ are and whether they really work.</P
+></DIV
+></DIV
+></DIV
+></DIV
+><DIV
+CLASS="section"
+><HR><H1
+CLASS="section"
+><A
+NAME="seealso"
+></A
+>5. See Also</H1
+><P
+></P
+><UL
+><LI
+><P
+>The <TT
+CLASS="function"
+>dlopen(3)</TT
+> man page. It explains
+ the purpose and the use of the <TT
+CLASS="function"
+>dlopen</TT
+>
+ API.</P
+></LI
+><LI
+><P
+>The article <A
+HREF="http://www.linuxjournal.com/article.php?sid=3687"
+TARGET="_top"
+>&#13; <I
+CLASS="citetitle"
+>Dynamic Class Loading for C++ on
+ Linux</I
+></A
+> by James Norton published on the
+ <A
+HREF="http://www.linuxjournal.com/"
+TARGET="_top"
+>Linux
+ Journal</A
+>.</P
+></LI
+><LI
+><P
+>Your favorite C++ reference about <TT
+CLASS="literal"
+>extern
+ "C"</TT
+>, inheritance, virtual functions,
+ <TT
+CLASS="literal"
+>new</TT
+> and <TT
+CLASS="literal"
+>delete</TT
+>. I
+ recommend [<SPAN
+CLASS="citation"
+>STR2000</SPAN
+>].</P
+></LI
+><LI
+><P
+>[<SPAN
+CLASS="citation"
+>ISO14882</SPAN
+>]</P
+></LI
+><LI
+><P
+>The <A
+HREF="http://www.dwheeler.com/program-library"
+TARGET="_top"
+>Program Library
+ HOWTO</A
+>, which tells you most things you'll ever need
+ about static, shared and dynamically loaded libraries and how
+ to create them. Highly recommended.</P
+></LI
+><LI
+><P
+>The <A
+HREF="http://tldp.org/HOWTO/GCC-HOWTO/index.html"
+TARGET="_top"
+>Linux GCC
+ HOWTO</A
+> to learn more about how to create libraries
+ with GCC.</P
+></LI
+></UL
+></DIV
+><A
+NAME="AEN295"
+></A
+><HR><H1
+><A
+NAME="AEN295"
+></A
+>Bibliography</H1
+><DIV
+CLASS="bibliomixed"
+><A
+NAME="AEN296"
+></A
+><P
+CLASS="bibliomixed"
+>&#13; ISO14482 <I
+>ISO/IEC 14482-1998 &#8212; The
+ C++ Programming Language</I
+>. Available as
+ PDF and as printed book from <A
+HREF="http://webstore.ansi.org/"
+TARGET="_top"
+>http://webstore.ansi.org/</A
+>.
+ </P
+></DIV
+><DIV
+CLASS="bibliomixed"
+><A
+NAME="AEN301"
+></A
+><P
+CLASS="bibliomixed"
+>&#13; STR2000
+ <SPAN
+CLASS="AUTHOR"
+>Bjarne Stroustrup</SPAN
+>
+ <I
+>The C++ Programming Language</I
+>, Special
+ Edition.
+ ISBN 0-201-70073-5.
+ Addison-Wesley.
+ </P
+></DIV
+></DIV
+>
+
+</body>
+</html>