Howto:export C + + classes from a dll__c++

Source: Internet
Author: User
Tags win32
The C + + programming language and Windows DLLs can live in peace. Download source-11.1 KB ContentsIntroduction C Language approach Handles calling conventions Exception Safety advantages C + + Disadvantages Naive: Exporting a Class What you are not What/get Exception Safety Advantages Disadvantages C + + mature approach:using N Abstract Interface How this works Why this works with the other compilers Using a Smart pointer Exception Safety Disadvantages What about STL Template Classes? Summary Introduction

The

Dynamic-link libraries (DLL) are a integrated part of the Windows platform from its very beginning. DLLs allow encapsulation of a piece of functionality in a standalone module with an explicit list of C functions that are Available for external users. In 1980 ' s, when Windows DLLs were introduced to the world, the only viable option to speak to broad development As C language. So, naturally, Windows DLLs exposed their functionality as C functions and data. Internally, a DLL may is implemented in the any language, the But in order to is used from other languages and environments, a DLL Interface should fall back to the lowest common denominator–the C language.

The

Using the C interface does not automatically mean this a developer should the up object give oriented. Even the C interface can be used to true object oriented programming, though it may be a tedious way of doing. Unsurprisingly, the second most used programming language in the world, namely C + +, could not help but to fall prey to the Temptation of a DLL. However, opposite to the "C language, where the binary interface between a caller and a callee is well-defined and widely a Ccepted, in the C + + world, there is no recognized Application binary interface (ABI). In practice, it means that binary code this is generated by a C + + compiler is not compatible with the other C + + compilers. Moreover, the binary code of the same C + + compiler May is incompatible with other versions to this compiler. All this makes exporting C + + classes from DLL quite a adventure.

The purpose of this article be to show several methods of exporting C + + classes from DLL module. The source code demonstrates different techniques of exporting the imaginary Xyz object. The Xyz object is very simple, and has only one method:foo.

This is the diagram of the object Xyz:

Xyz
int Foo (int)

The implementation of the Xyz object is inside a DLL and which can be distributed to a wide range of clients. A user can access Xyz functionality by:using pure C using a regular C + + class Using an abstract C + + interface

The source code consists of two Projects:xyzlibrary–a DLL Library project Xyzexecutable–a WIN32 console program that Uses "XyzLibrary.dll"

The Xyzlibrary project exports its code with the following handy macro:hide Copy code

#if defined (xyzlibrary_export)//Inside DLL
#   define XYZAPI __declspec   (dllexport)
#else//Outside DLL
#   define XYZAPI   __declspec (dllimport)
#endif  //Xyzlibrary_export

The xyzlibrary_export symbol is defined to the Xyzlibrary project, so XYZAPI macro expands (Into__declspec ORT) for the DLL build and into __declspec (dllimport) for the client build. C Language Approach Handles

The classic C language approach to object oriented programming is the usage of opaque, pointers., i.e. A user calls a function that is creates a object internally, and returns a handle to that object. Then, the user calls various functions that accept the handle as a parameter and performs all kinds of operations on the O Bject. A good example of the handle usage is the Win32 windowing API this uses An hwnd handle to represent a window. The Imaginary xyz object is exported via a C interface, like this:hide    Copy Code

typedef tagxyzhandle {} * xyzhandle;

Factory function that creates instances of the Xyz object.
Xyzapi xyzhandle apientry getxyz (VOID);

Calls Xyz.foo method.
Xyzapi int apientry Xyzfoo (xyzhandle handle, int n);
Releases Xyz instance and frees resources.
Xyzapi VOID apientry xyzrelease (xyzhandle handle);

Apientry is defined as __stdcall in WinDef.h header.

This is a example the how a client ' s C code might look like:hide Copy code

#include "XyzLibrary.h" ...

/* Create Xyz instance. * *
Xyzhandle hxyz = getxyz ();

if (hxyz)
{/
    * call Xyz.foo method. * *
    Xyzfoo (hxyz,);

    /* Destroy Xyz instance and release acquired. * *
    xyzrelease (hxyz);

    /* be defensive. * *
    hxyz = NULL;
}

With this approach, the a DLL must provide explicit functions for object creation and deletion. Calling conventions

It is important to remember to specify the calling convention for all exported. Omitted calling convention is a very common mistake this many do. As long as the default client ' s calling convention matches that's the DLL, everything works. But, the once the client changes its calling convention, it goes unnoticed by the developer until runtime. The xyzlibrary project uses The apientry macro, which is defined as __stdcall in the " WinDef.h "header file. Exception Safety

No C + + exception is allowed to cross over the DLL boundary. Period. The C language knows nothing about C + + exceptions, and cannot handle them. If The object method is needs to the "an error", then a return code should is used. Advantages A DLL can is used by the widest programming audience possible. Almost every modern programming language supports with interoperability C plain. C Run-time Libraries of a DLL and a client are independent of each. Since resource acquisition and freeing happens entirely inside a DLL module, a client is not affected by a DLL ' s choice of Crt. Disadvantages The responsibility of calling the right methods on the right instance of the ' an object ' rests on the user of a DLL. For example, in the following code snippet, the compiler won ' t is able to catch the error:hide    Copy Cod E

/* void* getsomeotherobject (void) is declared elsewhere.

* * Xyzhandle h = getsomeotherobject (); /* oops! Error:calling xyz.foo on Wrong object intance. * * Xyzfoo (H, a); 
The EXPLICIT function calls are required in order to create and destroy object instances. This is especially annoying for deletion of a instance. The client function must meticulously insert a call to Xyzrelease in all points of exit a function. If the developer forgets to call Xyzrelease, then resources are leaked because the compiler doesn ' t help to track the life Time of an object instance. Programming languages that support destructors or have a garbage collector could mitigate this problem by making a wrapper o Ver the C interface. If Object methods return or accept other objects as parameters, then the DLL author has to provide a proper C interface fo R these objects, too. The alternative is to fall the lowest common denominator, which is the "C language, and use only built-in types (lik e int, double, char*, etc.) As return types and method parameters. C + + Naive approach:exporting a Class

Almost every modern C + + compiler that exists on the Windows platform supports a C + + class from a DLL. Exporting a C + + class is quite similar to exporting C functions. All that a developer are required to does is the __declspec (dllexport/dllimport) specifier before the class name if th E whole class needs to is exported, or before the method declarations if only specific class methods need to be exported. This is a code snippet:hide Copy code

The whole CXYZ class is exported with all its methods and members.
class Xyzapi cxyz
{public
:
    int Foo (int n);

Only Cxyz::foo is exported.
class cxyz
{public
:
    xyzapi int Foo (int n);

There is no need to explicitly specify a calling convention for exporting classes or their. By default, the C + + compiler uses the __thiscall calling convention for class methods. However, due to different naming decoration schemes this are used by different compilers, the exported C + + class can only be used by the same compiler and by the same version of the compiler. This is a example of a naming decoration this is applied by the MS Visual C + + compiler:

Notice the decorated names are different from the original C + + names. Following is a screenshot to the same DLL module with name decoration deciphered by the Dependency Walker tool:

Only the MS Visual C + + compiler can use this DLL now. Both the DLL and the client code must is compiled with the same version of MS Visual C + + in order to ensure this namin G decoration scheme matches between the caller and the callee. This is a example of a client code that uses the Xyz object:hide Copy code

#include "XyzLibrary.h" ...
Client uses Xyz object as a regular C + + class.
CXYZ xyz;
Xyz. Foo (42);

As you can, the usage of a exported class is pretty much of the same as the usage of any other C + + class. Nothing special.

Important:using a DLL that exports C + + classes should be considered no different the Using a static library. All rules this apply to a static library that contains C + + code are fully applicable to a DLL that exports C + + classes. What You are not What for you

A careful reader must have already noticed this Dependency Walker tool Showes An additional exported member, which is T He cxyz& Cxyz::operator = (const cxyz&) assignment operator. What we are our C + + money at work. According to the C + + Standard, every class has four special member Functions:default constructor Copy Constructor Destruc Tor assignment operator (operator =)

If the author of a class does not declare and does not provide a implementation of this members, then the C + + compiler D Eclares them, and generates an implicit default implementation. In the case of the CXYZ class, the compiler decided, the default constructor, copy constructor, and the destructor are Trivial enough, and optimized them out. However, the assignment operator survived optimization and got exported from a DLL.

Important:marking the class as exported with the __declspec (dllexport) specifier tells the compiler to attempt to export Everything is related to the class. It includes all class data members, all class member functions (either explicitly declared, or implicitly generated by the compiler), all base classes of the class, and all their. Consider:

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.