Click here to Skip to main content
Email Password   helpLost your password?

Contents

Introduction

Dynamic-Link libraries (DLL) are an 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 audience was C language. So, naturally, Windows DLLs exposed their functionality as C functions and data. Internally, a DLL may be implemented in any language, but in order to be used from other languages and environments, a DLL interface should fall back to the lowest common denominator – the C language.

Using the C interface does not automatically mean that a developer should give up object oriented approach. Even the C interface can be used for true object oriented programming, though it may be a tedious way of doing things. 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 accepted, in the C++ world, there is no recognized application binary interface (ABI). In practice, it means that binary code that is generated by a C++ compiler is not compatible with other C++ compilers. Moreover, the binary code of the same C++ compiler may be incompatible with other versions of this compiler. All this makes exporting C++ classes from a DLL quite an adventure.

The purpose of this article is to show several methods of exporting C++ classes from a 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.

Here is the diagram of the object Xyz:

Xyz
int Foo(int)

The implementation of the Xyz object is inside a DLL, which can be distributed to a wide range of clients. A user can access Xyz functionality by:

The source code consists of two projects:

The XyzLibrary project exports its code with the following handy macro:

#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 only for the XyzLibrary project, so the XYZAPI macro expands into __declspec(dllexport) 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., handles. A user calls a function that creates an 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 object. A good example of the handle usage is the Win32 windowing API that uses an HWND handle to represent a window. The imaginary Xyz object is exported via a C interface, like this:

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.

Here is an example of how a client's C code might look like:

#include "XyzLibrary.h"

...

/* Create Xyz instance. */
XYZHANDLE hXyz = GetXyz();

if(hXyz)
{
    /* Call Xyz.Foo method. */
    XyzFoo(hXyz, 42);

    /* Destroy Xyz instance and release acquired resources. */
    XyzRelease(hXyz);

    /* Be defensive. */
    hXyz = NULL;
}

With this approach, 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 functions. Omitted calling convention is a very common mistake that many beginners do. As long as the default client's calling convention matches that of the DLL, everything works. But, once the client changes its calling convention, it goes unnoticed by the developer until runtime crashes occur. 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 properly. If an object method needs to report an error, then a return code should be used.

Advantages

Disadvantages

C++ Naive Approach: Exporting a Class

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

// The whole CXyz class is exported with all its methods and members.
//
class XYZAPI CXyz
{
public:
    int Foo(int n);
};

// Only CXyz::Foo method 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 methods. By default, the C++ compiler uses the __thiscall calling convention for class methods. However, due to different naming decoration schemes that 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. Here is an example of a naming decoration that is applied by the MS Visual C++ compiler:

C++ names are decorated or "mangled".

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

C++ names are undecorated by Dependency Walker.

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

#include "XyzLibrary.h"

...
// Client uses Xyz object as a regular C++ class.
CXyz xyz;
xyz.Foo(42);

As you can see, the usage of an exported class is pretty much 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 than using a static library. All rules that apply to a static library that contains C++ code are fully applicable to a DLL that exports C++ classes.

What You See Is Not What You Get

A careful reader must have already noticed that the Dependency Walker tool showes an additional exported member, that is the CXyz& CXyz::operator =(const CXyz&) assignment operator. What we see is our C++ money at work. According to the C++ Standard, every class has four special member functions:

If the author of a class does not declare and does not provide an implementation of these members, then the C++ compiler declares them, and generates an implicit default implementation. In the case of the CXyz class, the compiler decided that 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 that 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 members. Consider:

class Base
{
    ...
};

class Data
{
    ...
};

// MS Visual C++ compiler emits C4275 warning about not exported base class.
class __declspec(dllexport) Derived :
    public Base
{
    ...

private:
    Data m_data;    // C4251 warning about not exported data member.
};

In the above code snippet, the compiler will warn you about the not exported base class and the not exported class of the data member. So, in order to export a C++ class successfully, a developer is required to export all the relevant base classes and all the classes that are used for the definition of the data members. This snowball exporting requirement is a significant drawback. That is why, for instance, it is very hard and tiresome to export classes that are derived from STL templates or to use STL templates as data members. An instantiation of an STL container like std::map<>, for example, may require tens of additional internal classes to be exported.

Exception Safety

An exported C++ class may throw an exception without any problem. Because of the fact that the same version of the same C++ compiler is used both by a DLL and its client, C++ exceptions are thrown and caught across DLL boundaries as if there were no boundaries at all. Remember, using a DLL that exports C++ code is the same as using a static library with the same code.

Advantages

Disadvantages

C++ Mature Approach: Using an Abstract Interface

A C++ abstract interface (i.e., a C++ class that contains only pure virtual methods and no data members) tries to get the best of both worlds: a compiler independent clean interface to an object, and a convenient object oriented way of method calls. All that is required to do is to provide a header file with an interface declaration and implement a factory function that will return the newly created object instances. Only the factory function has to be declared with the __declspec(dllexport/dllimport) specifier. The interface does not require any additional specifiers.

// The abstract interface for Xyz object.
// No extra specifiers required.
struct IXyz
{
    virtual int Foo(int n) = 0;
    virtual void Release() = 0;
};

// Factory function that creates instances of the Xyz object.
extern "C" XYZAPI IXyz* APIENTRY GetXyz();

In the above code snippet, the factory function GetXyz is declared as extern "C". It is required in order to prevent the mangling of the function name. So, this function is exposed as a regular C function, and can be easily recognized by any C-compatible compiler. This is how the client code looks like, when using an abstract interface:

#include "XyzLibrary.h"

...
IXyz* pXyz = ::GetXyz();

if(pXyz)
{
    pXyz->Foo(42);

    pXyz->Release();
    pXyz = NULL;
}

C++ does not provide a special notion for an interface as other programming languages do (for example, C# or Java). But it does not mean that C++ cannot declare and implement interfaces. The common approach to make a C++ interface is to declare an abstract class without any data members. Then, another separate class inherits from the interface and implements interface methods, but the implementation is hidden from the interface clients. The interface client neither knows nor cares about how the interface is implemented. All it knows is which methods are available and what they do.

How This Works

The idea behind this approach is very simple. A member-less C++ class that consisting of pure virtual methods only is nothing more than a virtual table, i.e., an array of function pointers. This array of function pointers is filled within a DLL with whatever an author deems necessary to fill. Then, this array of pointers is used outside of a DLL to call the actual implementation. Bellow is the diagram that illustrates the IXyz interface usage.

Click on the image to view the full sized diagram in a new window:

Using IXyz interface from the outside of a DLL

The above diagram shows the IXyz interface that is used both by the DLL and the EXE modules. Inside the DLL module, the XyzImpl class inherits from the IXyz interface, and implements its methods. Method calls in the EXE module invoke the actual implementation in the DLL module via a virtual table.

Why This Works With Other Compilers

The short explanation is: because COM technology works with other compilers. Now, for the long explanation. Actually, using a member-less abstract class as an interface between modules is exactly what COM does in order to expose COM interfaces. The notion of a virtual table, as we know it in the C++ language, fits nicely into the specification of the COM standard. This is not a coincidence. The C++ language, being the mainstream development language for at least over a decade now, has been used extensively with COM programming. It is thanks to natural support for object oriented programming in the C++ language. It is not surprising at all that Microsoft has considered the C++ language as the main heavy-duty instrument for industrial COM development. Being the owner of the COM technology, Microsoft has ensured that the COM binary standard and their own C++ object model implementation in the Visual C++ compiler do match, with as little overhead as possible.

No wonder that other C++ compiler vendors jumped on the bandwagon and implemented the virtual table layout in their compilers in the same way as Microsoft did. After all, everybody wanted to support COM technology, and to be compatible with the existing solution from Microsoft. A hypothetical C++ compiler that fails to support COM efficiently is doomed to oblivion in the Windows market. That is why ,nowadays, exposing a C++ class from a DLL via an abstract interface will work reliably with every decent C++ compiler on the Windows platform.

Using a Smart Pointer

In order to ensure proper resource release, an abstract interface provides an additional method for the disposal of an instance. Calling this method manually can be tedious and error prone. We all know how common this error is in the C world where the developer has to remember to free the resources with an explicit function call. That's why typical C++ code uses RAII idiom generously with the help of smart pointers. The XyzExecutable project uses the AutoClosePtr template, which is provided with the example. The AutoClosePtr template is the simplest implementation of a smart pointer that calls an arbitrary method of a class to destroy an instance instead of operator delete. Here is a code snippet that demonstrates the usage of a smart pointer with the IXyz interface:

#include "XyzLibrary.h"
#include "AutoClosePtr.h"

...
typedef AutoClosePtr<IXyz, void, &IXyz::Release> IXyzPtr;

IXyzPtr ptrXyz(::GetXyz());

if(ptrXyz)
{
    ptrXyz->Foo(42);
}

// No need to call ptrXyz->Release(). Smart pointer
// will call this method automatically in the destructor.

Using a smart pointer will ensure that the Xyz object is properly released, no matter what. A function can exit prematurely because of an error or an internal exception, but the C++ language guarantees that destructors of all local objects will be called upon the exit.

Exception Safety

In the same way as a COM interface is not allowed to leak any internal exception, the abstract C++ interface cannot let any internal exception to break through DLL boundaries. Class methods should use return codes to indicate an error. The implementation for handling C++ exceptions is very specific to each compiler, and cannot be shared. So, in this respect, an abstract C++ interface should behave as a plain C function.

Advantages

Disadvantages

What About STL Template Classes?

The Standard C++ Library containers (like vector, list, or map) and other templates were not designed with DLL modules in mind. The C++ Standard is silent about DLLs because this is a platform specific technology, and it is not necessarily present on other platforms where the C++ language is used. Currently, the MS Visual C++ compiler can export and import instantiations of STL classes which a developer explicitly marks with the __declspec(dllexport/dllimport) specifier. The compiler emits a couple of nasty warnings, but it works. However, one must remember that exporting STL template instantiations is in no way different from exporting regular C++ classes, with all accompanying limitations. So, there is nothing special about STL in that respect.

Summary

The article discussed different methods of exporting a C++ object from a DLL module. Detailed description is given of the advantages and disadvantages for each method. Exception safety considerations are outlined. The following conclusions are made:

The C++ programming language is a powerful, versatile, and flexible development instrument.

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralWhat about virtual inheritance?
Member 4608161
18:28 31 Jan '10  
Is virtual inheritance permissible where dll binary compatibility is a concert? I probably know the answer to this already when I did a simple test between mingw and borland's free compiler 5.5. Consider the following example:

//header file for abtract interface
//included in test executable (compiled with bcc) that
//imports from dll (compiled with mingw)
class CBaseFoo{};

class IBaseFoo : public virtual CBaseFoo
{
public:
virtual void runB() = 0;
virtual void Destroy() = 0;
virtual int getint() = 0;
};

extern "C" DLLAPI IBaseFoo* CALLCONV CreateFoo();

//in implementation cpp file for the dll
//compiled with mingw
class BaseFooImp : public IBaseFoo
{
public:
BaseFooImp() {}
void runB() { }
int getint() { return 1; }
void Destroy() { delete this; }
};

IBaseFoo* CALLCONV CreateFoo()
{
return new BaseFooImp;
}

//main() for test executable
int main()
{
IBaseFoo *fooinstance = CreateFoo();

//this line throws an exception if
//the dll is compiled with a different tool
//e.g. this test executable compiled with bcc and test.dll compiled with mingw
fooinstance->getint();
}


Thanks
GeneralRe: What about virtual inheritance?
Alex Blekhman
22:20 31 Jan '10  
No, virtual inheritance is not supported across different compilers. The problem with virtual inheritance is that a lot of bookeeping should be maintained by compiler in order to have things work properly. Compiler should be aware of a place of the class in inheritance hierarchy, c'tors and d'tors must be arranged in a special order, etc etc. All this is quite different between compilers. So, unfortunately virtual inheritance renders class interfaces not compatible.

Alex
Generalsource file path in c++
JinXu
19:50 19 May '09  
Hi, Alex,

I use Visual Studio to generate my DLLs. But I find that c++ source paths are often stored in the generated DLLs as strings, even in release version. Frown Can you tell me why?

Thanks a lot!

Hello world!

GeneralRe: source file path in c++
Alex Blekhman
23:36 19 May '09  
I don't know why. This is the way MS linker builds executable modules. However, you can select the .PDB file during debug session manually if VC++ IDE doesn't find the one specified in the .EXE/.DLL module.
GeneralStatic library
Osman Kevin
15:57 21 Mar '09  
In my project, I want to eliminate the dependency of DLL, so I am planning to use static library, does this method apply to the static library as well ?
GeneralRe: Static library
Alex Blekhman
2:51 22 Mar '09  
If you want to use static library, then you don't need to worry about DLL techniques at all. just compile your code as a .LIB, thne link with it. That's all.
Generalcalling convention for each method in abstract class is required
chipmunk
3:13 18 Feb '09  
Great article, thanks !

But I found out that APIENTRY macro is required for each method in abstract interface.
While I used different Microsoft C++ compilers - there were all ok. But when I tried out MinGW and Borland C++ - method arguments were corrupted. Adding macros solved this problem:
// The abstract interface for Xyz object.          
// No extra specifiers required.
struct IXyz
{
virtual int APIENTRY Foo(int n) = 0; // APIENTRY is required
virtual void APIENTRY Release() = 0; // APIENTRY is required
};

GeneralRe: calling convention for each method in abstract class is required
Alex Blekhman
4:05 18 Feb '09  
I don't have Borland compiler handy to check this. However, if your compiler supports __declspec(novtable) specifier, then you may apply it to the IXyz interface:
struct __declspec(novtable) IXyz
{
virtual int Foo(int n) = 0;
virtual void Release() = 0;
};
Pure virtual methods should not require any exporting as long as you use only basic types (or interface pointers) as parameters.
Generalderiving the interface in EXE module
arif.setiawan
13:28 6 Feb '09  
Hi,

First, thank you for this great article.

I want to know your opinion about my case.

Suppose that I want to derive a child class from abstract interface in EXE module and this child class can also use then implementation of the interface in a class inside the dll which accessible through factory function. An example would be :

I have a class:
class IAttribute
{
public:
virtual int Save(const char *filename) = 0;
virtual int Load(const char *filename) = 0;

protected:
int left, right, top, bottom;
};

The actual implementation will be hidden in the dll by a class
class CAttribute : public IAttribute
{
CAttribute();
~CAttribute();
int Save(const char *filename);
int Load(const char *filename);
}

which accessible by factory function GetAttribute()

Now I want to have a class in the MFC EXE which can draw the the attributes, so I make a new class
class CEntity : public IAttribute
{
CEntity ();
~CEntity ();
void Draw(CDC* dc);
int Save(const char *filename);
int Load(const char *filename);
}


Since the IAttribute provide no implementation of Save() and Load(), I add a member pointer to the CAttribute so I can use functions defined in the dll.
class CEntity : public IAttribute
{
public:
CEntity ();
... // same as above

private:
IAttribute *m_pAtttibute;
}


Please tell me what your opinion about this, is this even possible? or not correct from OOP perspective, really a bad design, or maybe there is another approach that better than this.

I am doing this to make the dll MFC-independent and in some application scenerio I just need to load the attribute only.

Thank you.
GeneralRe: deriving the interface in EXE module
Alex Blekhman
1:27 7 Feb '09  
Hello,

First of all, you cannot have data members in IAttribute class. Having data members in a class effectively makes it compiler dependent. If you need data members, then provide getter/setter functions:

struct IAttribute
{
...
virtual int Left(void) const = 0;
virtual void Left(int l) = 0;
};

class CAttribute : public IAttribute
{
public:
// IAttribute implementation
...
virtual int Left() const { return m_left; }
virtual void Left(int l) { m_left = l; }

private:
int m_left;
};

Now regarding CEntity class. There is no any problem in using data member of type IAttribute that points to actual implementation in a DLL. You have two options of reusing DLL's implementation:

1. Containment/Delegation (forwarding calls):

class CEntity : public IAttribute
{
public:
...

int Save(const char *filename)
{
return m_pAttibute->Save(filename);
}

int Load(const char *filename)
{
return m_pAttibute->Load(filename);
}
};

2. Aggregation:

class CEntity
{
public:

...

IAttribute *GetAttribute() const { return m_pAttibute; }
private:
IAttribute *m_pAttibute;
}

Both methods are acceptable and quite common. Which of them is most suitable for your project depends on your needs.

BTW, I'd suggest to use wide characters for filenames, so you will be able to handle non-English filenames, as well.
GeneralRe: deriving the interface in EXE module
arif.setiawan
19:35 8 Feb '09  
Thank you for your explanation.
Smile
GeneralAbstract interface - question about disadvantages
mariusz102102
22:26 18 Nov '08  
You wrote: "An abstract interface method cannot return or accept a regular C++ object as a parameter."

Could you explain me this limitation? What will (can) happen when I pass regular C++ object to interface method?

Best regards,
Mariusz
GeneralRe: Abstract interface - question about disadvantages
Alex Blekhman
23:49 18 Nov '08  
This problems stems from the binary incompatibility between C++ compilers. When you pass a C++ object as a parameter, then teh compiler should know how to call necessary copy constructors, destructors, etc; what to do if any of this throws an exception; how to allocate/deallocate memory, if the object (or one of its members) requires that, etc. All this is compiler specific and cannot be shared across different compilers.

If you want to accept C++ objects as a parameters (or return them from methods) then you should treat such code as a static library, which can be used with the same compiler only.
GeneralImporting to C#
prodakn
11:27 10 Nov '08  
That is a very good explanation for the "C++ Mature Approach".

Using this approach, would it be possible to access the C++ virtual method from a C# wrapper?
GeneralRe: Importing to C#
Alex Blekhman
12:20 10 Nov '08  
Hello,

Unfortunately C# cannot call C++ methods (be it global function, a method of an abstract class or whatever). The C# programming language has different object layout and method calling mechanics. That's what Microsoft introduced C++/CLI - the C++ programming language that supports both native and managed programming. C++/CLI is meant to be the bridge between native world and .NET world.

If you need to use existing C++ code in .NET assembly, then C++/CLI is the way to go. You can make a wrapper assembly with C++/CLI that calls native C++ internally. Then such assembly could be used from other managed languages. As an alternative, you can expose a C++ class with plain C functions, which C# knows how to call via interop.

HTH
Alex
GeneralRe: Importing to C#
prodakn
17:14 10 Nov '08  
Thanks for your quick reply. I will try the wrapper assembly with C++/CLI.

Edit:
So I started looking into writing such a wrapper in C++/CLI. I'm relatively unfamiliar with this language, but it looks like I can #include the original C++ header file which uses the abstract interface, and implement it as I would with C++; would this be the route to go?

Appreciate your help,

Daniel
GeneralRe: Importing to C#
Alex Blekhman
20:55 10 Nov '08  
Yes, C++/CLI is the full featured C++ plus additional extensions that provide support for managed programming. The resulting code is compiled into CLI, not to native binaries. If you want to connect between existing C++ DLL and .NET assembly, then you can create a regular managed class, which will call native C++ DLL.

In order to practice that, in Visual C++ go to new project wizard and select there Visual C++ -> CLR -> CLR Console Application. Wizard will generate an empty project very similar to C# console aplication. You can include any C++ header in that project and use native DLL's without any problem.
Generalunit testing
rioch
23:03 23 Oct '08  
How would I go about unit testing classes in the dll that aren't exported?
GeneralRe: unit testing
Alex Blekhman
22:13 2 Nov '08  
Hi. Sorry for delayed response, I've been on vacation last week.

Actually, there is nothing special about internal C++ classes that reside within a DLL. You, as an author of the DLL have full control over the source code. So, naturally, you develop test cases (using your favourite testing framework) for internal classes in the same manner as you do this for any other code you write.

Of course, TDD approach requires that you bear in mind the testing process during design of software components, be it single C++ class or full blown DLL module. There is no simple answer to your question. Testing approach greatly depends on the nature of a class, its interdependencies with other classes, etc.

Basically, I do similar unit tests for C++ classes within a DLL regardless of whether they are exported or not. As a testing framework I use CppUnit most of the time. Sometimes a project can require slightly different testing framework, which is more tuned to the needs of the project. Although it's a lot of a code to write for decent testing coverage, but it pays off nicely during acceptance period before releases.
GeneralRe: unit testing
rioch
3:02 5 Nov '08  
No problem, thanks for replying, and I hope you enjoyed your holiday! Smile

I think the problem lies in that the test framework runs in a separate project, which includes the dll projects to be tested. Since my test code is in a different project, only the exported classes are visible, which leaves a lot of classes untestable.
GeneralRe: unit testing
Alex Blekhman
3:23 5 Nov '08  
Engineering is all about tradeoffs. For each module/class one should decide where to draw a line and what to test. Ideally, we should test everything. It may involve some kind of a macro that will export every class for test configuration builds. However, in practice testing every single class/function can be prohibitively expensive.

Maybe in your case testing at the module level is good enough. After all, as long as the module behaves as documented it is less important (from the test point of view) how the module is implemented inside. In my opinion, if you treat the module as a black box and make comprehensive test harness that successfully covers all functionality (including garbage input and extreme input), then you can assume quite reliably that the module is tested well enough.
GeneralRe: unit testing
rioch
1:26 26 Feb '09  
I'm not sure if I agree. Some of the code is gui based, but includes complex elements such as zooming, which is in a non-exported class. This zoom code is a prime candidate for unit testing, and doing this via the dll interface is nigh on impossible.

I can think of two solutions:

1) Write test classes in the dll and export them also. These classes can be picked up by the test program.
2) Export everything (I've never been a fan of exporting classes).
GeneralRe: unit testing
Alex Blekhman
2:49 26 Feb '09  
There is also third option: make special build for testing. In that build one could export more than in regular release build etc. However, as I wrote in the other post, it's a matter of tradeoff.
GeneralAuto-releasing with boost::shared_ptr
Chris Marski
15:18 26 Sep '08  
I just wanted to point out that it is also possible to use boost::shared_ptr for auto-releasing:

#include <boost/mem_fn.hpp>

#include <boost/shared_ptr.hpp>

boost::shared_ptr<IFoo> foo (::GetFoo (), boost::mem_fn (&IFoo::Release))

(More interesting smart-pointer techniques here: http://www.boost.org/doc/libs/release/libs/smart_ptr/sp_techniques.html[^])

It was a pleasure to read such a crystal-clear article. How about expanding it and covering other platforms like Linux or Darwin.
QuestionDLLs and exception
Member 3843328
12:42 22 Sep '08  
I wonder why DLLs and exception propagation do not mix.

Is it because including <exception> introduces a STL dependency? (I checked STLport 5.1.4 - it seems to include the compilers' <exception> only ...)

Or do different compilers really implement exception handling differently? Could it be that even different compiler switches in the DLL and the client cause trouble?

Roland


Last Updated 31 Aug 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2010