Jump to content

Wrapper library: Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
Tags: Mobile edit Mobile web edit
(40 intermediate revisions by 36 users not shown)
Line 1: Line 1:
{{Short description|Software library for programming}}
In [[computer programming]], a [[Library (computing)|library]] is a collection of subroutines or classes used to develop software. Libraries expose interfaces which clients of the library use to execute library routines.
'''Wrapper libraries''' (or library wrappers) consist of a thin layer of code (a "[[shim (computing)|shim]]") which translates a [[Library (computing)|library]]'s existing interface into a compatible interface. This is done for several reasons:


* To refine a poorly designed or complicated interface
'''Wrapper libraries''' (or library wrappers) consist of a thin layer of code which translates a library's existing interface into a compatible interface. This is done for several reasons:
* Allow code to work together which otherwise cannot (e.g. incompatible data formats)
* Enable cross language and/or [[Run-time system|runtime]] interoperability


Wrapper libraries can be implemented using the [[Adapter pattern|adapter]], [[Facade pattern|façade]], and to a lesser extent, [[Proxy pattern|proxy]] [[Design pattern (computer science)|design patterns]].
*To refine a poorly designed or complicated interface.
*Allow code to work together which otherwise cannot (e.g. Incompatible data formats).
*Enable cross language and/or [[Run time (computing)|runtime]] interoperability.


== Structure and implementation ==
Wrapper libraries are implemented using the [[Adapter pattern|Adapter]], [[Facade pattern|Facade]], and to a lesser extent, [[Proxy pattern|Proxy]] [[Design pattern (computer science)|design patterns]].

== Structure / Implementaiton ==
The specific way in which a wrapper library is implemented is highly specific to the environment it is being written in and the scenarios which it intends to address. This is especially true in the case when [[#Cross_Language.2FRuntime_Interoperability|cross language/runtime interoperability]] is a consideration.
The specific way in which a wrapper library is implemented is highly specific to the environment it is being written in and the scenarios which it intends to address. This is especially true in the case when [[#Cross_Language.2FRuntime_Interoperability|cross language/runtime interoperability]] is a consideration.


===Example Implementation===
=== Example ===

The following provides a general illustration of a common wrapper library implementation. In this example, a C++ interface acts as a "wrapper" around a C-language interface.
The following provides a general illustration of a common wrapper library implementation. In this example, a C++ interface acts as a "wrapper" around a C-language interface.


==== C Interface ====
==== C interface ====
<source lang="C">
<syntaxhighlight lang="C">
int pthread_mutex_init(pthread_mutex_t * mutex , pthread_mutexattr_t * attr);
int pthread_mutex_init(pthread_mutex_t * mutex , pthread_mutexattr_t * attr);
int pthread_mutex_destroy (pthread_mutex_t * mutex);
int pthread_mutex_destroy (pthread_mutex_t * mutex);
int pthread_mutex_lock (pthread_mutex_t * mutex );
int pthread_mutex_lock (pthread_mutex_t * mutex );
int pthread_mutex_unlock (pthread_mutex_t * mutex );
int pthread_mutex_unlock (pthread_mutex_t * mutex );
</syntaxhighlight>
</source>


==== C++ Wrapper ====
==== C++ wrapper ====
<source lang="cpp">
<syntaxhighlight lang="cpp">
class Mutex
class Mutex
{
{
Line 31: Line 29:


public:
public:
Mutex()
Mutex() : mutex(0)
{
{
pthread_mutex_init(&mutex, 0);
pthread_mutex_init(&mutex, 0);
Line 43: Line 40:


private:
private:

friend class Lock;
friend class Lock;


Line 59: Line 55:
class Lock
class Lock
{
{
private:
Mutex& mutex;
Mutex &mutex;

public:
public:
Lock(Mutex& mutex):mutex(mutex){mutex.lock();}
Lock(Mutex &mutex): mutex{mutex}
{
~Lock(Mutex& mutex):mutex(mutex){mutex.unlock();}
mutex.lock();
}

~Lock()
{
mutex.unlock();
}
};
};
</syntaxhighlight>
</source>


The original C-interface can be regarded as error prone, particularly in the case where users of the library forget to unlock an already locked mutex. The new interface effectively utilizes [[Resource acquisition is initialization|RAII (Resource Acquisition is Initialization)]] in the new <tt>Mutex</tt> and <tt>Lock</tt> classes to ensure <tt>Mutex</tt>s are eventually unlocked and <tt>pthread_mutex_t</tt> objects are automatically released.
The original C interface can be regarded as error prone, particularly in the case where users of the library forget to unlock an already locked mutex. The new interface effectively utilizes [[Resource acquisition is initialization|RAII (Resource Acquisition is Initialization)]] in the new {{mono|Mutex}} and {{mono|Lock}} classes to ensure {{mono|Mutex}}s are eventually unlocked and {{mono|pthread_mutex_t}} objects are automatically released.


The above code closely mimics the implementation of <tt>boost::scoped_lock</tt> and <tt>boost::mutex</tt> which are part of the [http://www.boost.org/doc/libs/1_38_0/doc/html/thread.html boost::thread] library.
The above code closely mimics the implementation of {{mono|boost::scoped_lock}} and {{mono|boost::mutex}} which are part of the [http://www.boost.org/doc/libs/1_38_0/doc/html/thread.html boost::thread] library.


===Driver Wrappers===
=== Driver wrappers ===
{{Further|Driver wrapper}}
{{See |Driver_wrapper}}

==Cross Language/Runtime Interoperability==


== Cross-language/runtime interoperability ==
Some wrapper libraries exist to act as a bridge between a client application and a library written using an incompatible technology. For instance, a [[Java (programming language)|Java]] application may need to execute a [[system call]]. However system calls are typically exposed as C library functions. To resolve this issue Java implements wrapper libraries which make these system calls callable from a Java application.
Some wrapper libraries exist to act as a bridge between a client application and a library written using an incompatible technology. For instance, a [[Java (programming language)|Java]] application may need to execute a [[system call]]. However system calls are typically exposed as C library functions. To resolve this issue Java implements wrapper libraries which make these system calls callable from a Java application.


In order to achieve this, languages like Java provide mechanisms that make this possible. Some examples of these mechanisms include:
In order to achieve this, languages like Java provide a mechanism called [[foreign function interface]] that makes this possible. Some examples of these mechanisms include:


===Java Native Interface===
* [[Java Native Interface|Java Native Interface (JNI)]]
[[Java Native Interface|Java Native Interface (JNI)]]
* [[Java Native Access|Java Native Access (JNA)]]
* [https://docs.python.org/library/ctypes.html A foreign function library for Python]
===ctypes Library (Python)===
* [[Managed Extensions for C++|Managed Extensions]]
[http://docs.python.org/library/ctypes.html A foreign function library for Python]
* [[SWIG|SWIG (Simplified Wrapper and Interface Generator)]]
===Managed Extensions (C#)===
[[Managed Extensions for C++|Managed Extensions]]

==Existing Wrapper Libraries==


== Existing wrapper libraries ==
Some examples of existing wrapper libraries:
Some examples of existing wrapper libraries:
*[http://www.winehq.org/ Wine]
*[http://sourceware.org/pthreads-win32/ Pthreads for WIN32]
*[http://pyopengl.sourceforge.net/ OpenGL Bindings for Python]
*[http://www.tangentsoft.net/mysql++/ MySQL++]


* [http://sourceware.org/pthreads-win32/ Pthreads for WIN32]
{{DEFAULTSORT:Wrapper Library}}
* [http://pyopengl.sourceforge.net/ OpenGL Bindings for Python]
[[Category:Computer libraries]]
* [http://www.tangentsoft.net/mysql++/ MySQL++]
* [http://code.google.com/p/javacv/ JavaCV]
* [[WineD3D]]


==See also==
* [[Wrapper function]]
* [[Wrapper pattern]]
* [[Glue code]]


[[Category:Computer libraries]]
{{comp-sci-stub}}

Revision as of 00:55, 23 March 2024

Wrapper libraries (or library wrappers) consist of a thin layer of code (a "shim") which translates a library's existing interface into a compatible interface. This is done for several reasons:

  • To refine a poorly designed or complicated interface
  • Allow code to work together which otherwise cannot (e.g. incompatible data formats)
  • Enable cross language and/or runtime interoperability

Wrapper libraries can be implemented using the adapter, façade, and to a lesser extent, proxy design patterns.

Structure and implementation

The specific way in which a wrapper library is implemented is highly specific to the environment it is being written in and the scenarios which it intends to address. This is especially true in the case when cross language/runtime interoperability is a consideration.

Example

The following provides a general illustration of a common wrapper library implementation. In this example, a C++ interface acts as a "wrapper" around a C-language interface.

C interface

int pthread_mutex_init(pthread_mutex_t * mutex , pthread_mutexattr_t * attr);
int pthread_mutex_destroy (pthread_mutex_t * mutex);
int pthread_mutex_lock (pthread_mutex_t * mutex );
int pthread_mutex_unlock (pthread_mutex_t * mutex );

C++ wrapper

class Mutex
{
     pthread_mutex_t mutex;

public:
     Mutex() 
     {
          pthread_mutex_init(&mutex, 0);
     }

     ~Mutex()
     {
          pthread_mutex_destroy(&mutex);
     }

private:
     friend class Lock;

     void lock()
     {
          pthread_mutex_lock(&mutex);
     }

     void unlock()
     {
          pthread_mutex_unlock(&mutex);
     }
};

class Lock
{
private:
      Mutex &mutex;

public:
      Lock(Mutex &mutex): mutex{mutex}
      {
            mutex.lock();
      }

      ~Lock()
      {
            mutex.unlock();
      }
};

The original C interface can be regarded as error prone, particularly in the case where users of the library forget to unlock an already locked mutex. The new interface effectively utilizes RAII (Resource Acquisition is Initialization) in the new Mutex and Lock classes to ensure Mutexs are eventually unlocked and pthread_mutex_t objects are automatically released.

The above code closely mimics the implementation of boost::scoped_lock and boost::mutex which are part of the boost::thread library.

Driver wrappers

Cross-language/runtime interoperability

Some wrapper libraries exist to act as a bridge between a client application and a library written using an incompatible technology. For instance, a Java application may need to execute a system call. However system calls are typically exposed as C library functions. To resolve this issue Java implements wrapper libraries which make these system calls callable from a Java application.

In order to achieve this, languages like Java provide a mechanism called foreign function interface that makes this possible. Some examples of these mechanisms include:

Existing wrapper libraries

Some examples of existing wrapper libraries:

See also