Files
secondo/include/DynamicLibrary.h
2026-01-23 17:03:45 +08:00

208 lines
7.6 KiB
C++

/*
----
This file is part of SECONDO.
Copyright (C) 2004, University in Hagen, Department of Computer Science,
Database Systems for New Applications.
SECONDO is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
SECONDO is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with SECONDO; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
----
//paragraph [10] title: [{\Large \bf ] [}]
//paragraph [11] title: [{\large \bf ] [}]
//paragraph [12] title: [{\normalsize \bf ] [}]
//paragraph [21] table1column: [\begin{quote}\begin{tabular}{l}] [\end{tabular}\end{quote}]
//paragraph [22] table2columns: [\begin{quote}\begin{tabular}{ll}] [\end{tabular}\end{quote}]
//paragraph [23] table3columns: [\begin{quote}\begin{tabular}{lll}] [\end{tabular}\end{quote}]
//paragraph [24] table4columns: [\begin{quote}\begin{tabular}{llll}] [\end{tabular}\end{quote}]
//[--------] [\hline]
//characters [1] verbatim: [$] [$]
//characters [2] formula: [$] [$]
//characters [4] teletype: [\texttt{] [}]
//[ae] [\"a]
//[oe] [\"o]
//[ue] [\"u]
//[ss] [{\ss}]
//[<=] [\leq]
//[#] [\neq]
//[tilde] [\verb|~|]
1 Header File: Dynamic Library Management
January 2002 Ulrich Telle
1.1 Overview
The module ~DynamicLibrary~ provides support for dynamic linking, which allows
a process to link libraries at run-time. Dynamically loaded libraries are very
similar to ordinary shared libraries; they are usually built as standard shared
libraries. The main difference is that the libraries aren't automatically
loaded at program link time or start-up; instead, there is an application
programming interface (API) for opening a library, looking up symbols, handling
errors, and closing the library. Often it is a very useful feature for
applications to be able to load and execute code from an external source at the
runtime. Plugins or modules are good examples.
Unix-like operating systems, i.e. Linux and Solaris, provide this facility
by offering the *dl* functions (~dlopen~, ~dlsym~, ~dlerror~ and ~dlclose~)
as a mechanism for loading libraries at runtime. The Win32 API provides the
functions ~LoadLibrary~, ~GetProcAddr~ and ~FreeLibrary~ for managing dynamic
link libraries (DLL).
Unfortunately there are considerable differences in the implementation
and functionality of the dynamic loading mechanism on these platforms.
While Unix-like systems usually perform a complete linking step resolving
unresolved function and data references, Windows resolves only references
from the loaded DLL to other DLLs. To make things worse, this is only done,
when the DLL was created using appropriate ~import libraries~. Otherwise
it's up to the DLL itself to resolve references. One has to keep these
deficiencies in mind when writing portable programs.
In most cases an application loads a dynamic library, tries to locate a
function by using its known name and then to execute the code of the
function to perform the requested task. Using a C function interface
locating the address of a function is quite straight forward since the
names seen in the C source code and seen by the linker are essentially
the same. Using C++ things get more complicated since due to the name
mangling the C++ compiler performs to make calling functions type-safe
and to allow overloading of functions.
For example the function name ~init~ might look like
"init\_int23\@myclass\@qbe\_ev\_abc"[4] or something similar strange. So
finding the function isn't an easy task, but there is a way out of the
problem when there exists at least *one* C call protected from name
mangling with "extern C"[4] in the dynamic library that returns a pointer
to a class instance. Clever as it is this ~trick~ solves only part of
the problem since the calling program wont actually have any knowledge
about the object, unless there is a common parent class from which the
object class in the dynamic library is inherited. Although one is limited
to calling those methods on the returned objects that had definitions in
the base class, it still allows a great deal of flexibility through the
use of virtual methods.
Implementing C++ classes in a DLL usually only works when used within a
C++ application built with the same compiler due to name mangling and heap
memory management. Beware of mixing run time libraries since one might end
up with heap corruption; application and DLL should both use the same debug
versus non debug run time libaries.
1.2 Interface methods
This module offers the following routines to manipulate dynamic libraries:
[23] Creation/Removal & Library loading & Information retrieval \\
[--------]
DynamicLibrary & Load & GetFunctionAddress \\
[tilde]DynamicLibrary & Unload & GetLibraryName \\
& IsLoaded & GetLastErrorMessage \\
1.3 Class "DynamicLibrary"[1]
The class ~DynamicLibrary~ implements a portable wrapper to the operating
system specific mechanisms to load libraries at runtime.
*/
#ifndef DYNAMIC_LIBRARY_H
#define DYNAMIC_LIBRARY_H
#include "SecondoConfig.h"
#ifdef SECONDO_WIN32
#include <windows.h>
#endif
#include<string>
class SDB_EXPORT DynamicLibrary
{
public:
DynamicLibrary();
/*
Initializes the ~DynamicLibrary~ object.
Once the object is constructed, use the method ~Load~
to dynamically link to a dynamic library while the process is running.
*/
virtual ~DynamicLibrary();
/*
Destroys an instance of ~DynamicLibrary~
The method ~Unload~ is call implicitly.
*/
bool Load( const std::string& libraryName );
/*
Loads a dynamic library ~libraryName~ into a process while it is
running (dynamic linking).
The method returns "true"[4] on success, otherwise "false"[4].
On failure use method ~GetLastErrorMessage~ to get an error
message.
*/
bool Unload();
/*
Unloads a dynamic library from a process while it is running.
The method returns "true"[4] on success, otherwise "false"[4].
On failure use method ~GetLastErrorMessage~ to get an error
message.
*/
bool IsLoaded() const;
/*
Returns "true"[4] if a dynamic library is currently loaded into the process.
*/
std::string GetLibraryName() const;
/*
Returns the name of the currently loaded dynamic library.
An empty string is returned when no library is loaded.
*/
void* GetFunctionAddress( const std::string& functionName );
/*
Finds the function named ~functionName~ and returns a function pointer to it.
If the function cannot be found, a null pointer is returned.
*/
std::string GetLastErrorMessage();
/*
Returns the error message text of the last failed class method.
An empty string is returned when no error occurred.
The internal message buffer is emptied.
*/
protected:
#ifdef SECONDO_WIN32
HANDLE libraryHandle; // Handle of library
#else
void* libraryHandle;
#endif
std::string libName; // Name of currently loaded library
std::string errorMessage; // Error message text
private:
void SetErrorMessage();
/*
Is used to create an error message when one of dynamic library system calls failed.
The method ~GetLastErrorMessage~ returns this message to the user on request.
*/
// Do not use the following functions.
DynamicLibrary( const DynamicLibrary& other );
int operator==( const DynamicLibrary& other ) const;
DynamicLibrary& operator=( const DynamicLibrary& other);
};
#endif // DYNAMIC_LIBRARY_H