diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 17:43:19 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-24 17:43:19 +0000 |
commit | 0292059f4a16434600564cfa3f0ad2309a508a54 (patch) | |
tree | d95953cd53011917c4df679b96aedca39401b54f /doc/html/ksquirrel-libs-olibs2.html | |
download | libksquirrel-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.html | 1620 |
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" +><<A +HREF="mailto:[email protected]" +>[email protected]</A +>></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 +> 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 +> 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 +> 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 +> 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 +> In this document, I have the pleasure of acknowledging (in + alphabetic order): + </P +><P +></P +><UL +><LI +><P +>Joy Y Goodreau <TT +CLASS="email" +><<A +HREF="mailto:joyg (at) us.ibm.com" +>joyg (at) us.ibm.com</A +>></TT +> for + her editing.</P +></LI +><LI +><P +>D. Stimitis <TT +CLASS="email" +><<A +HREF="mailto:stimitis (at) idcomm.com" +>stimitis (at) idcomm.com</A +>></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 +> Feedback is most certainly welcome for this document. Send + your additions, comments and criticisms to the following email + address: <TT +CLASS="email" +><<A +HREF="mailto:[email protected]" +>[email protected]</A +>></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 — like classes, member functions, exception + specifications — 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 <iostream> +#include <dlfcn.h> + + +int main() { + using std::cout; + using std::cerr; + + cout << "C++ dlopen demo\n\n"; + + // open the library + cout << "Opening hello.so...\n"; + void* handle = dlopen("./hello.so", RTLD_LAZY); + + if (!handle) { + cerr << "Cannot open library: " << dlerror() << '\n'; + return 1; + } + + // load the symbol + cout << "Loading symbol hello...\n"; + typedef void (*hello_t)(); + hello_t hello = (hello_t) dlsym(handle, "hello"); + if (!hello) { + cerr << "Cannot load symbol 'hello': " << dlerror() << + '\n'; + dlclose(handle); + return 1; + } + + // use it to do the calculation + cout << "Calling hello...\n"; + hello(); + + // close the library + cout << "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 <iostream> + +extern "C" void hello() { + std::cout << "hello" << '\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" { + … }</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 — which must expose a clearly defined interface + — 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 <iostream> +#include <dlfcn.h> + +int main() { + using std::cout; + using std::cerr; + + // load the triangle library + void* triangle = dlopen("./triangle.so", RTLD_LAZY); + if (!triangle) { + cerr << "Cannot load library: " << dlerror() << '\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 << "Cannot load symbols: " << dlerror() << '\n'; + return 1; + } + + // create an instance of the class + polygon* poly = create_triangle(); + + // use the class + poly->set_side_length(7); + cout << "The area is: " << poly->area() << '\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 <cmath> + +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" +> <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" +> ISO14482 <I +>ISO/IEC 14482-1998 — 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" +> 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> |