DLL export and interface for DLL in Visual C++ - c++

I have two Visual C++ projects (in Visual Studio 2008 environment) and one of them has to use the others classes and functionalities. So I found this which is pretty understandable but I have one point that needs clarification.
So let's say first project is ProjA and the second one is ProjB. ProjB needs to use the classes and funcs. of ProjA as I told in beginning. But there must be only one interface between these two projects which is a simple object like this:
class A
{
public:
void write(data);
void read (data);
}
so this must be the interface class which ProjB has to use, but in ProjA after write function is called there are a lot of oprations are done in seperate cpp files and other classes and funcs...
So my question is do I need to use dllexport functionalities only for class A or do I have to use them in all the other class and function definitions which are used inside ProjA as well? And how to write the interface file?
Thanks indeed...

Use dllexport only for the A class, provided that the type of the data parameter is not another class defined in ProjA.
When a class is "exported", all the code for that class is ans stays in it's DLL. If the ProjB knows nothing else from the ProjA classes, it should works.
Be sure to keep the two Dlls in sync (build otions, type of C RunTime...)

Related

Consuming a C++ class reference from an external "plugin" library that doesn't have access to the class implementation

I'm using the Boost.DLL library for my project in order to offload its functionality into a suite of pluggable modules. The core application provides headers defining various structs and classes that will be used both within the core application, and which will (in some cases) be passed to plugins when they need to perform various tasks.
One of the initial things I need to do is pass a class ServiceCatalog to each plugin's initialization method, to allow that plugin to register various capabilities with the core application. I've grouped the definitions I'd like to share with my plugins into a header called core.h, and I'm referencing this header both in more application and in my plugin projects.
ServiceCatalog has a number of larger functions that, to me, make sense to offload into a cpp file, rather than trying to bundle them all into the header file. I'd still like the plugin to know the "shape" of the class though, because, while I don't need it to instantiate the class, I need it to be able to call instance methods.
However because I'm referencing the header file in the plugin, but not the cpp file containing the implementation, I get "unresolved external symbol" errors when linking. This makes sense on a basic level of course (i.e. what would happen if the plugin tried to instantiate something it doesn't have access to the implementation for?) but there doesn't seem to be any way (that I can find) to declare that the class is, I guess, "extern" or something?
Do I literally need to use a base abstract class to achieve this? Such a solution feels a little convoluted. I guess I could replace my class with a struct containing some function pointers instead.
What approach do you recommend? In a nutshell, I want my core application to be able to pass instances of things to my plugins, where each thing has a number of related methods that can be called.
// core.h, "main.exe"
class ServiceCatalog
{
public:
void complex_method_with_external_implementation();
}
//plugin.cpp, "plugin.dll"
#include "core.h"
void register_plugin(ServiceCatalog* catalog)
{
catalog->complex_method_with_external_implementation();
}
If I'm understanding this right, the ServiceCatalog object is only created by the "main.exe" program, and not in any of the plugins. If that's the case, you can declare the functions that can be called by the plugins as virtual.
class ServiceCatalog
{
public:
virtual void complex_method_with_external_implementation();
}
Then all of the reference to them will be in the vtable, referenced by the constructor. The plugins will access the functions thru the vtable so they don't need any sort of export.
There are issues with versioning, as adding new 'exports' needs to be done in such a way not to mess up the existing layout of the vtable (you need to add them after all existing virtual functions, not insert them in between two existing virtual functions), and you can't remove any, either, without replacing them with something else.

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.

How to redesign c++ classes?

I have a bunch of classes like this:
class A
{
public:
std::string s;
std::vector<int> v;
int a;
}
That I'm trying to export to be used in a dll. I want clients to be able to use the class like this:
A a;
a.s = "abc";
b.v.push_back(4);
But because vector and string cannot be exported, this isn't possible. Besides providing getters and setters for each member and using an abstract interface that has those getters and setters, is there any way around this?
Having STL classes at the DLL interface is a very fragile design: if you do so, all the clients of the DLL must be built using the same version of the Visual C++ compiler, and the same settings (e.g. same _ITERATOR_DEBUG_LEVEL, etc.), and the same flavor of the CRT.
This is highly constraining.
You may want to follow different paths. For example, you could build a pure-C interface API layer wrapping your C++ classes, and export that from the DLL. DLL with a pure C interface are just fine (for example, think of the Win32 APIs).
Then you can distribute an header file in which this pure-C interface is wrapped in C++ classes, ready to be used by clients (for example, think of ATL/WTL, which are convenient C++ wrappers around pure-C Win32 APIs).
Or you could follow a COM-ish approach, exporting C++ interfaces.
You can find more details about that in this article:
HowTo: Export C++ classes from a DLL
A DLL just provides references to global variables and functions, since you class uses neither, you cannot export anything from your class from the DLL. Typically you would put your class into a header file and share the header file between both your DLL and the harness executable just like you will do with a C++ project having multiple source files.

C++ compiler independent DLLs using abstract interface

I followed the guide at CodeProject and built a DLL with an abstract interface and exported the factory functions using the extern "C" command along with __declspec(dllexport) and __cdecl and by doing this the article claims that the DLL becomes compiler independent with a clean interface. However when using the DLL on two different versions of g++ the non-standard ABI created the standard c++ problems with DLL calling. In addition to the CodeProject article I also used an article from MinGW in order to be able to create multiple instances of the class.
How is it then possible to make the DLL compiler independent? and if this is not possible, is it then possible to instantiate a class within a DLL and make the functions pure C but calling the C++ functions related to the instantiated class?
Have you tried to reproduce exactly the example that was given there? And what was the failure? You have to consider that not only your class, but any other class like std::string can't be used directly. That said, I wouldn't try to reinvent the wheel but use some kind of component framework like COM.
To answer your second part, consider this:
// internal class
struct X
{
void jump();
};
// compiler-independent C interface
struct X;
struct X* x_alloc(void);
void x_jump(struct X* x, float height);
void x_free(struct X* x);
This works. I have no idea what exactly you tried and what didn't work for you, there's just not enough info to tell.

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