Exporting C++ classes from DLL - c++

I came across this article on Code Project that talks about using an abstract interface as an alternative to exporting an entire class from a C++ DLL to avoid name mangling issues. The author has a Release() method in his interface definition that is supposed to be called by the user to free the class object's resources after using it. To automate the calling of this method the author also creates an std::auto_ptr<T>-like class that calls the Release() method before deleting the object.
I was wondering whether the following approach would work instead:
#include <memory>
#if defined(XYZLIBRARY_EXPORT) // inside DLL
# define XYZAPI __declspec(dllexport)
#else // outside DLL
# define XYZAPI __declspec(dllimport)
#endif // XYZLIBRARY_EXPORT
// The abstract interface for Xyz object.
// No extra specifiers required.
struct IXyz
{
virtual int Foo(int n) = 0;
//No Release() method, sub-class' destructor does cleanup
//virtual void Release() = 0;
virtual ~IXyz() {}
};
// Factory function that creates instances of the Xyz object.
// Private function, do not use directly
extern "C" XYZAPI IXyz* __stdcall GetXyz_();
#define GetXyz() std::auto_ptr<IXyz>( GetXyz_() )
Of course, GetXyz() can be a global function defined in the header instead of a #define. The advantage to this method would be that we don't need to cook up our own derivative of auto_ptr that calls the Release() method.
Thanks for your answers,
Ashish.

by doing this, you risk calling delete (in your process, within auto_ptr's destructor) on an object that is not created by the matching call to new() (that is done inside the factory function, hence inside the dll). Trouble guaranteed, for instance when your dll is compiled in release mode while the calling process in debug mode.
The Release() method is better.

This is exactly how COM works. Avoiding re-inventing this wheel if you already target the Win32 API. Using smart pointers to store COM interface pointers is very common in Windows programming, their destructor calls the Release() method. Take a peek at the MSDN docs for _com_ptr_t and CComPtr for ideas.

The restriction you face if this is a public API is the CRT that the different modules will be linked against and that the CRT that creates the object also needs to be the one to delete it.
There will be a mess if you don't choose the right CRT
Anything sharing memory management should use CRT (or other memory allocation) as external lib - ie. MSVC: Multi-threaded DLL (/MD)
Given that, then there is not even a need for the subclass to achieve your purpose.

Related

Correctly defining DLL-interfaces with C++11/14

I've read several times that passing STL objects like vector and string outside of a DLL boundary is bad practice because different compiler versions can generate different code for STL objects. Therefore, you should design a C-style interface and not pass STL objects at all. However, there are still some things unclear to me:
1. What is the 'boundary' of a DLL?
Is it right to say, that the boundary is where code is beeing compiled on DLL side? What if I define a .h file inside a DLL (f.e. to write a factory class) and use that header file in a different project? Is that .h file inside or outside the boundary of the DLL and why?
2. What is contained in a DLL?
Let' say I have a class Foo:
class Foo
{
public:
__declspec(dllexport) void f1(); //instantiates v1 inside function
private:
unique_ptr<vector<int>> v1 = nullptr;
}
If I only mark the function f1() with __declspec(dllexport), only this function should be contained in the DLL. How does the code inside f1() know what v1 is if v1 isn't contained in the DLL?
3. Passing objects out of a DLL-boundary using unique_ptr
I'm using unique_ptr almost everytime in my project. From what I understand, returning a unique_ptr from a DLL would be bad practice because unique_ptr is an STL object. How can I instantiate an object inside the DLL and return a unique_ptr to it?
4. Why does defining interfaces or using PIMPL help to define an DLL interface?
I still have to convert my STL classes to C-style objects. And in the project using the DLL, I would have to somehow wrap the C-style objects inside STL classes again. I don't see any advantage of using interfaces or PIMPL in this case.
Also, if I define an interface (class with pure virtual functions), wouldn't this have the same effect as just declaring the functions in my class with __declspec(dllexport)?
class IFoo
{
public:
virtual ~IFoo() = 0 {};
virtual void f1() = 0;
}
class Foo : public IFoo
{
public:
void f1();
//__declspec(dllexport) void f1(); //why use an interface if I can just declare the functions like this?
}
How is the DLL-STL problematic solved in modern C++ 11/14 libraries? Are there any modern open-source libraries that I can have a look at?
Unfortunately STL types aren't consistent across compilers. Even different versions of Visual Studio have differences.
The boundary is where the code is compiled. If you have an implementation in a header file in your library, then the compiler used to compile the EXE will compile the code. This is potentially very bad because what the code in the EXE thinks is the data is different to what the code in the DLL thinks is the data. (You need to look out for differences like this especially if you have #ifs in a struct definition and you need to be explicit about packing).
The only way to be sure is to define all your own types (being careful of packing) and not use STL. This is what DLL libraries usually do.
Interfaces can enable the user to dynamically link to the library. Using __declspec(dllexport) requires a static linking; that is the EXE has to link to the .lib generated when you compiled the DLL to be able to access all the functions. This means amongst other things you can't update the DLL without the EXE having to be recompiled (probably - you can get away with this in some circumstances, but it's not a good idea).
By dynamically linking you can update the DLL or add functionality to the DLL without relinking the EXE as long as you don't change your interfaces. The EXE might call LoadLibrary() on the DLL and GetProcAddress() to access one function that returns an interface. Everything else including data types passed as parameters are interfaces (i.e. contain only pure virtual functions) or simple structs. This is how the basic level of COM works.
To answer question 2, when you declare something as __declspec(dllexport) you are stating that this is part of the interface to the DLL - something that is accessible to the component that loads the DLL. Anything declared without __declspec(dllexport) should be present within the DLL but will not be available to be called/used by an external component.

Using std::unique_ptr in an exported class

I have a class in a DLL that looks something like this:
#ifdef LIB_EXPORT
#define LIB_API __declspec(dllexport)
#else
#define LIB_API __declspec(dllimport)
#endif
...
class LIB_API MyClass {
public:
// ...public interface...
private:
// ...some private fields...
std::unique_ptr<OtherClass> otherPtr_;
};
Now, I think this could be a problem: if the client code uses a slightly different version of unique_ptr, the memory layout of a MyClass object effectively becomes different from what the code in the DLL might expect.
I don't really want to resort to the Pimpl idiom to hide unique_ptr from the public header. I could, potentially, roll my own simplified version of unique_ptr (I only need a subset of its functionality, for example I don't need custom deleters). But, before I try that, are there any other methods to resolve this?
The problem you've surmised is quite real, and it applies not only to layout of Standard library classes, but also your own classes. Unless your class meets the standard-layout rules, different compilers are not expected to use the same in-memory layout, even given exactly the same source code. The answer is that C++ classes shouldn't be exported at all.
Case #1: If you want unique_ptr for managing the lifetime of public objects of the DLL:
Export a factory function and deletion function from the DLL, and put a wrapper class inside the public header. The wrapper exists completely within the client, and therefore uses the client's version of unique_ptr only.
__declspec(dllexport) is NOT used on the wrapper class.
Case #2: If the DLL uses unique_ptr internally:
Instead of pimpl, you should use inheritance. The public header file contains a base class with protected constructor, pure virtual member functions and no data members at all. Again, __declspec(dllexport) is NOT used. A dllexport factory function is used to create new instances. Inside the DLL, you inherit from this interface type, the derived class adds all the data members and function bodies. None of the data members are ever seen by the client, so you can freely use C++ objects and the layout used is local to the DLL.
A side effect of both of these is that trivial member functions won't be inlined, which may negatively effect performance. But calling into the DLL for every member access is the only way to achieve decoupling.

invalid memory when using classes from a dll

this is the first time I've tried to export a class from a dll.
what I've done is:
- crated an interface (only pure virtual methods)
- implemented this interface in the dll with a class that wont be exported
- the class has a release method that calls delete on its this pointer
- created a Factory class with a static method that returns a pointer to the concrete class but as the interface. this class is exported.
- the deletion of the returned object is done by calling its release method.
I tuck all this from this tutorial about classes in dlls.
The problem is that when I use this dll in another project everything goes ok until I call the release function on the object.
Then it shows an assertion failed window with the message "_ASSERTE(_BLOCK_TYPE_IS_VALID(pHead->nBlockUse));"
Did this happened to anybody else?
I know this is as simple as forgetting to use std:: when you start C++ , but as I said I just started this.
Thanks!
Is your factory function defined in the header? If it is, and the new for creating the object is in the header then calling delete from within the DLL can cause this error. The factory function needs to be exported by the DLL, only the declaration must appear in the header.
For instance, your header should look line this:
class MyInterface
{
public:
virtual void DoSomething() = 0;
virtual ~MyInterface() {}
};
__declspec(dllexport) MyInterface * __stdcall MyInterfaceFactory();
The implementation of MyInterfaceFactory() must be contained within the DLL.
Thanks for your answers, and I'm sorry I started this for nothing!
The problem was very simple but hidden behind the interfaces , factory , and some other stuff.
I was returning a pointer to an object that was declared as static because it has to be a singleton. Then I was trying to release this object. BANG heap corruption!!
My singleton object shouldn't have a release function in the first place;
I'll solve this by extracting the release function in a separate interface , that will be implemented only by non static objects.

What do these C++ code snippets do?

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif
Why define these tags?
CSortHeaderCtrl::CSortHeaderCtrl()
: m_iSortColumn( -1 )
, m_bSortAscending( TRUE )
{
}
What are the two functions after colon used for?
BEGIN_MESSAGE_MAP(CSortHeaderCtrl, CHeaderCtrl)
//{{AFX_MSG_MAP(CSortHeaderCtrl)
// NOTE - the ClassWizard will add and remove mapping macros here.
//}}AFX_MSG_MAP
END_MESSAGE_MAP()
Are there any similar things in C# like this?
What's this used for?
virtual ~CSortHeaderCtrl();
Why set the destructor function to be virtual?
void CSortHeaderCtrl::Serialize( CArchive& ar )
When will this function be called?
Is this extended from parent?
By the way, when you want to extend a MFC class, what document you will read?
Since we don't know what function it has, what function can we override?
The following is the header file:
/* File: SortHeaderCtrl.h
Purpose: Provides the header control, with drawing of
the arrows, for the list control.
*/
#ifndef SORTHEADERCTRL_H
#define SORTHEADERCTRL_H
#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
class CSortHeaderCtrl : public
CHeaderCtrl { // Construction public:
CSortHeaderCtrl();
// Attributes public:
// Operations public:
// Overrides // ClassWizard generated
virtual function overrides
//{{AFX_VIRTUAL(CSortHeaderCtrl)
public: virtual void Serialize(CArchive& ar);
//}}AFX_VIRTUAL
// Implementation public: virtual
~CSortHeaderCtrl();
void SetSortArrow(
const int iColumn,
const BOOL bAscending );
// Generated message map functions
protected:
void DrawItem(LPDRAWITEMSTRUCT lpDrawItemStruct );
int m_iSortColumn;
BOOL m_bSortAscending;
//{{AFX_MSG(CSortHeaderCtrl) //
NOTE - the ClassWizard will add and
remove member functions here.
//}}AFX_MSG
DECLARE_MESSAGE_MAP() };
//{{AFX_INSERT_LOCATION}} // Microsoft
Visual C++ will insert additional
declarations immediately before the
previous line.
#endif // SORTHEADERCTRL_H
Question 1: The DEBUG_NEW is probably so the 'new' operator records some extra information about where and when a block was allocated to help in detecting memory leaks, see this. The THIS_FILE[] static char array simple holds the current filename, probably used by the debug 'new'
Question 2: This is an C++ initialization list.
Question 3: The destructor is declared virtual because there are other virtual members and this is a derived class. The 'delete' operator needs to know the correct size of the object it is deleting, along with which actual desctructor to call, see this
As for question 2: those are not functions. They are initializer
lists for members of CSortHeaderCtrl. You can think of it as
being equivalent to:
m_iSortColumn = -1;
m_bSortAscending = TRUE;
I emphasise "think of it", because for members that are
classes, only the copy constructor will be invoked (instead of first the
copy constructor and then the assignment operator).
Note that, with an initializer list, the initialization order
is not determined by the order it is written, but by order
of the class inheritance and by order of declaration of the member
variables.
Why define these tags ?
See jcopenha's answer.
What is the two functions after colon used for ?
See Peter's answer.
Is there any similar things in C# like this ? What's this used for ?
In C# it might be implemented as a dictionary of delegates.
It's called a "message map" (probably described in one of the subsections of MFC Library Reference Message Handling and Mapping).
Its contents are typically created/edited via the IDE "Class Wizard" (not edited manually using the code/text editor).
Why set the destructor function to be virtual ?
In C++, if a class might be subclassed then its destructor should almost always be virtual (because otherwise if it's not virtual and you invoke it by deleting a pointer to the superclass, the destructor of the subclass wouldn't be invoked).
When will this function be called ?
That's probably described here: MFC Library Reference Serialization in MFC.
is this extended from parent?
Acording to that link I just gave above, it's the CObject ancestor class: "MFC supplies built-in support for serialization in the class CObject. Thus, all classes derived from CObject can take advantage of CObject's serialization protocol."
By the way, when you want to extend a MFC class, what document you will read?
The MFC reference documentation.
Since we don't know what function it have, what function we can override...
You can typically override everything that virtual and not private. I think you can also/instead use the Class Wizard that's built-in to the IDE.
CSortHeaderCtrl is apparently a 3rd-party class, though, not a Microsoft class. Perhaps it's authors/vendor wrote some documentation for it, if you're supposed to be using it.
First of all, CSortHeaderCtrl has a virtual destructor because in C++ it is proper practice to make destructors virtual.
Destructors are made virtual in base classes because it means that the destructors in classes derived from the base will be called.
If destructors in derived classes aren't called (i.e. the base class destructor is non-virtual), then they will most likely leak memory and leave resources (streams, handles, etc) open.
The rest of the code you posted is generated by Visual Studio to handle common or redundant MFC tasks for you, for example mapping Win32 messages to member functions of your class or window. You shouldn't touch this code, as it is likely to be overriden or you will break it and have a debugging related headache coming your way.
When should my destructor be virtual?
http://www.parashift.com/c++-faq-lite/virtual-functions.html#faq-20.7

C++: Dynamically loading classes from dlls

For my current project I want to be able to load some classes from a dll (which is not always the same, and may not even exist when my app is compiled). There may also be several alternative dll's for a given class (eg an implementation for Direct3D9 and one for OpenGL), but only one of the dlls will be loaded/used at any one time.
I have a set of base classes that define the interface plus some basic methods/members (ie the ones for refrence counting) of the classes I want to load, which the dll projects then derive from when creating there classes.
//in namespace base
class Sprite : public RefCounted//void AddRef(), void Release() and unsigned refCnt
{
public:
virtual base::Texture *GetTexture()=0;
virtual unsigned GetWidth()=0;
virtual unsigned GetHeight()=0;
virtual float GetCentreX()=0;
virtual float GetCentreY()=0;
virtual void SetCentre(float x, float y)=0;
virtual void Draw(float x, float y)=0;
virtual void Draw(float x, float y, float angle)=0;
virtual void Draw(float x, float y, float scaleX, flota scaleY)=0;
virtual void Draw(float x, float y, float scaleX, flota scaleY, float angle)=0;
};
The thing is I'm not sure how to do it all so that the executable and other dlls can load and use these classes since ive only ever used dlls where there was only one dll and I could have the Visual Studio linker sort it all out using the .lib file I get when compileing dll's.
I dont mind using factory methods for instancing the classes, many of them do already by design (Ie a sprite class is created by the main Graphics class, eg Graphics->CreateSpriteFromTexture(base::Texture*)
EDIT:
When I needed to write some c++ dlls for use in python I used a library called pyCxx. The resulting dll basicly only exported one method, which created an instance of the "Module" class, which could then contain factory methods to create other classes etc.
The resulting dll could be imported in python just with "import [dllname]".
//dll compiled as cpputill.pyd
extern "C" void initcpputill()//only exported method
{
static CppUtill* cpputill = new CppUtill;
}
class CppUtill : public Py::ExtensionModule<CppUtill>
{
public:
CppUtill()
: Py::ExtensionModule<CppUtill>("cpputill")
{
ExampleClass::init_type();
add_varargs_method("ExampleClass",&CppUtill::ExampleClassFactory, "ExampleClass(), create instance of ExampleClass");
add_varargs_method("HelloWorld", &CppUtill::HelloWorld, "HelloWorld(), print Hello World to console");
initialize("C Plus Plus module");
}
...
class ExampleClass
...
static void init_type()
{
behaviors().name("ExampleClass");
behaviors().doc ("example class");
behaviors().supportGetattr();
add_varargs_method("Random", &ExampleClass::Random, "Random(), get float in range 0<=x<1");
}
How exactly does that work, and could I use it in a purely c++ enviroment to solve my problem here?
Easiest way to do this, IMHO, is to have a simple C function that returns a pointer to an interface described elsewhere. Then your app, can call all of the functions of that interface, without actually knowing what class it is using.
Edit: Here's a simple example.
In your main app code, you create a header for the interface:
class IModule
{
public:
virtual ~IModule(); // <= important!
virtual void doStuff() = 0;
};
Main app is coded to use the interface above, without any details on the actual implementation of the interface.
class ActualModule: public IModule
{
/* implementation */
};
Now, the modules - the DLL's have the actual implementations of that interface, and those classes don't even have to be exported - __declspec (dllexport) isn't needed. The only requirement for the modules is to export a single function, that would create and return an implementation of the interface:
__declspec (dllexport) IModule* CreateModule()
{
// call the constructor of the actual implementation
IModule * module = new ActualModule();
// return the created function
return module;
}
note: error checking left out - you'd usually want to check, if new returned the correct pointer and you should protect yourself from the exceptions that might be thrown in the constructor of the ActualModule class.
Then, in your main app, all you need is to simply load the module (LoadLibrary function) and find the function CreateModule (GetProcAddr function). Then, you use the class through the interface.
Edit 2: your RefCount (base class of the interface), can be implemented in (and exported from) the main app. Then all your module would need to link to the lib file of the main app (yes! EXE files can have LIB files just like DLL files!) And that should be enough.
You are re-inventing COM. Your RefCounted class is IUnknown. Your abstract class is an interface. A COM server in a DLL has an entrypoint named DllGetClassObject(), it is a class factory. There is lots of documentation available from Microsoft on COM, poke around a bit to see how they did it.
[Edit: whilst I was composing all this, Paulius Maruška edited his comment to say basically the same. So apologies for any duplication. Though I suppose you've now got one for spare :)]
Off the top of my head, and assuming Visual C++...
You need to use LoadLibrary to load a DLL in dynamically, then use GetProcAddress to retrieve from it the address of a function that will create the actual derived class that the DLL code implements. How you decide to do this precisely is up to you (the DLLs need finding, the way the expose their functionality needs specifying, etc.) so for now let's assume that plugins only provides new Sprite implementations.
To do this, decide on the signature of the function in the DLL that the main program will call to create one of these new sprites. This one looks suitable:
typedef Sprite *(*CreateSpriteFn)();
Then, from the main program, you'll have to load a DLL (again, how you find this DLL is up to you) and get the sprite creation function from it. I've decided that the sprite creation function will be called "CreateSprite":
HMODULE hDLL=LoadLibrary(pDLLName);
CreateSpriteFn pfnCreateSprite=CreateSpriteFn(GetProcAddress(hDLL,"CreateSprite"));
Then to actually create one of these, just call the function:
Sprite *pSprite=(*pfnCreateSprite)();
Once you are done with the DLL and there are no objects left that were created by it, you then use FreeLibrary to get rid of it:
FreeLibrary(hDLL);
To create a DLL that sports this interface, write the code for the derived class and so on then somewhere in the DLL code provide the CreateSprite function that the calling program needs, using the appropriate signature:
__declspec(dllexport)
extern "C"
Sprite *CreateSprite()
{
return new MyNewSprite;
}
The dllexport thing means that you can use GetProcAddress to pick this function up by name, and the extern "C" ensures that the name is unmangled and doesn't end up as "CreateSprite#4" or something like.
Two other notes:
GetProcAddress returns 0 if it couldn't find the function, so you can use this to scan through a list of DLLs (e.g., returned from FindFirstFile and friends) looking for DLLs that support the interface, and/or try to find multiple entry points and support multiple types per plugin.
if the main program is going to delete the sprite using the delete operator, this requires that both DLL and main program are built using the same runtime library, so that the main program's delete and the DLL's new are both using the same heap. You can work around this to some extent by having the DLL provide a DeleteSprite function, that deletes the sprite using the DLL's runtime library rather than the main program's, but you still have to take care about the rest of your program, so you may just want to force DLL writers to use the same runtime library as your program. (I wouldn't say you'd be in good company by doing this, but it's not uncommon. 3D Studio MAX requires this, for example.)
Perhaps you want to look into DLL Delay-Loading (http://www.codeproject.com/KB/DLL/Delay_Loading_Dll.aspx) - this will give you what you want without having to work too hard for it