Implementing an interface in dll which is declared in main app - C++ - c++

I have a main app which has an interface(abstract class) and this interface need to have implementations both in main app and an external dll.
I will be using the pointer to this interface to access the methods, so i will be assigning pointer to address of the any one of the implementations based on some condition.
How can this be achieved?
I came across a question in stack overflow where the answer marked as solution says
An interface in main app
class IModule
{
public:
virtual ~IModule(); // <= important!
virtual void doStuff() = 0;
};
can be implemented in main app
class ActualModule: public IModule
{
/* implementation */
};
And can export a function from dll to return pointer to implementation in dll
__declspec (dllexport) IModule* CreateModule()
{
// call the constructor of the actual implementation
IModule * module = new ActualModule();
// return the created function
return module;
}
How will dll come to know that something like IModule exists?
Can i mark the IModule as extern and use in dll?

'How will dll come to know that something like IModule exists?'
Because the dll code will include the header file where IModule is declared. Header files are the way to share declarations between different source files. Dlls make no difference to this, and there is no need to mark IModule as extern.
BTW I would do this
virtual ~IModule() {} // <= important!

Related

C++ dynamic library with public api that obscures dependent libraries

I am trying to create a multi-platform library in C++ for use by C++ consumer applications. Call my library A. I want to ship a dynamic library file per target platform, and a header file (call this export.h) that the consumer app could use to compile and execute. My library depends on a third-party open-source library, written in c, which is difficult to link to correctly; call this library B.
In order to save my consumers the pains of linking to B, I want to abstract every call to it so that the consumer need not even have a single header file from B. Consumer app (C) should be able to compile with only A.dll, B.dll and export.h; and run with only A.dll and B.dll as dependencies (substituting the platform-specific suffix for a shared library as needed).
B defines a great many types, mostly structs. (B is not written in objective c, although it probably should have been.) Part of A's job is to produce classes that contain and manage groups of structs around logical lines, which are readily apparent. C needs to call functions belonging to classes in A, so the function prototypes need to be in export.h, but the B types cannot be in export.h or else C will need to include headers from B.
Is there a syntax that lets me define the public members of a class (in A) without also defining all the private members?
Obviously, there are no public members in A that rely on types from B. The closest thing I've found so far is this question. Opaque pointers may be part of the solution, but C needs access to functions of classes in A. I really don't want to write a helper function for every public A class member, though that would probably work. Any ideas?
Edit: As requested, explanation code.
Worker.h:
#include <SomeThirdPartyLib.h>
class Worker {
public:
Worker();
~Worker();
void DoWork();
private:
Truck t;
}
SomeThirdPartyLib.h:
typedef struct TruckS {
char data[200];
char* location;
} Truck;
Worker.cpp:
#include "worker.h"
Worker::Worker() {}
Worker::~Worker() {}
Worker::DoWork() {
t.location = "Work";
}
main.cpp:
#include <export.h>
int main(int argc, char** argv) {
Worker w();
w.DoWork();
}
Now I'm looking for the syntax to put in export.h that would allow this external application to be compiled using that header and my dll, but without requiring access to SomeThirdPartyLib.h.
Here is a technique that may be close to what you want to achieve.
You can define an interface that relies only on public interfaces from A, and therefore lacks any dependency on B. The interface class includes a factory. This interface would be part of the header file for your library.
class Interface {
public:
virtual void foo () = 0;
virtual void bar () = 0;
static std::unique_ptr<Interface> make ();
virtual ~Interface () = default;
};
In a source file of your library, you would include header files for both A and B, and create an implementation of the interface as well as a definition of the factory.
class Implementation : public Interface {
//...
};
std::unique_ptr<Interface>
Interface::make () {
return std::make_unique<Implementation>();
}
So, users of your library get access to the interface, and can call the public methods without any knowledge of private members or private methods.
Try it online!

MSVC C++ Name Mangling From String On Runtime

First i will start with the reason i need name mangling on runtime.
I need to create a bridge between dll and its wrapper
namespace Wrapper
{
class __declspec(dllexport) Token
{
public:
virtual void release() {}
};
}
class __declspec(dllexport) Token
{
public:
virtual void release(){}
};
The idea is to use dumpin to generate all the mangled names of the dll holding class token and than demangled them.
?release#Token##UAEXXZ --> void Token::release(void)
after that i want to convert is to match the Wrapper so i will need to change the function name
void Token::release(void) --> void Wrapper::Token::release(void)
and then i need to mangle it again so i can create a def file that direct the old function to the new one.
?release#Token##UAEXXZ = ?release#Token#Wrapper##UAEXXZ
all this process needs to be on run time.
First and the easiest solution is to find a function that mangle strings but i couldn't find any...
any other solution?
The Clang compiler is ABI-compatible with MSVC, including name mangling.
The underlying infrastructure is part of the LLVM project, and I found llvm-undname which demangles MSVC names. Perhaps you can rework it to add the Wrapper:: namespace to symbols and re-mangle.
You can find inspiration about mangling names in this test code.
If you are allowed to change the DLL, I'd usually use a different approach, by exporting extern "C" getter function (that does not mangle thus doesn't need demangling) and using virtual interface to access the class (note that the virtual interface doesn't need to be dllexported then). Your Token interface seems to be virtual anyway.
Something along those lines (not tested, just to show the idea):
DLL access header:
class Token // notice no dllexport!
{
protected:
// should not be used to delete directly (DLL vs EXE heap issues)
virtual ~Token() {}
virtual void destroyImpl() = 0; // pure virtual
public:
static inline void destroy(Token* token) {
// need to check for NULL otherwise virtual call would segfault
if (token) token->destroyImpl();
}
virtual void doSomething() = 0; // pure virtual
};
extern "C" __declspec(dllexport) Token * createToken();
DLL implementation:
class TokenImpl: public Token
{
public:
virtual void destroyImpl() {
delete this;
}
virtual void doSomething() {
// implement here
}
};
extern "C" __declspec(dllexport) Token * createToken()
{
return new TokenImpl;
}
Usage:
// ideally wrap in RAII to be sure to always release
// (e.g. can use std::shared_ptr with custom deleter)
Token * token = createToken();
// use the token
token->doSomething();
// destroy
Token::destroy(token);
With shared::ptr (can also create a typedef/static inline convenience creator function in the Token interface):
std::shared_ptr<Token> token(createToken(),
// Use the custom destroy function
&Token::destroy);
token->doSomething()
// token->destroy() called automatically when last shared ptr reference removed
This way you only need to export the extern-C creator function (and the release function, if not part of the interface), which will then not be mangled thus easy to use via the runtime loading.

Polymorphic DLL exports

I am currently working on a project that uses a DLL and an application that uses the DLL. The DLL is exported as an abstract base class header and a concrete implementation derived from the abstract base, as usual:
---- TaskInterface.h ----
class Task {
public:
virtual int func1(void) = 0;
virtual int func2(void) = 0;
};
extern "C" __declspec(dllexport) Task * APIENTRY newTask();
--- Task.h ---
class TaskImpl : public Task
{
public:
virtual int func1(void);
virtual int func2(void):
};
Task * APIENTRY newTask()
{
return static_cast<Task*>( new TaskImpl );
}
--- Task.cpp ---
int TaskImpl::func1(void)
{
// ...
}
int TaskImpl::func2(void)
{
// ...
}
This works so far as intended, the application includes "AbstractTask.h" and then calls the respective function defined by class TaskImpl:
--- TheApplication.cpp ---
Task aTask = newTask();
aTask->func1();
aTask->func2();
// ...
However, now the Application discovers that what the default implementation in class TaskImpl does is not enough and therfore defines within its own scope a new derived class, like so:
--- AppImpl.h ---
#include "TaskInterface.h"
class AppImpl : public Task
{
int func1(void) = { /* new stuff */ }
int func2(void) = { /* new stuff */ }
};
and then defines in TheApplication.cpp:
--- TheApplication.cpp ---
#include "AppImpl.h"
ApplImp * aNewTask = static_cast<Task*>(newTask());
aNewTask->func1();
aNewTask->func2();
In what context do you think func1() and func2() are called? Correct: It's still the concrete implementation inside the DLL class TaskImpl and not the derivates defined by class AppImpl.
And basically this is my problem: I want to use a default implementation from inside a DLL, but I want to be able to expand it on the Application side, so unless I have explicitly overriden a function in ApplImp.h, I fall back to the one defined in TaskImpl inside the DLL.
Is this possible? If so, what am I doing wrong? If not, how could I accomplish something equivalent?
I already toyed with exporting both "TaskInterface.h" and "Task.h" and then have ApplImp.h include the concrete class in the DLL, but the compile doesn't like that for obvious reasons => can't export newTask() twice.
Any help is appreciated!
As you need to allocate and deallocate via the DLL anyway, I'd suggest providing a wrapper class alongside the DLL. This wrapper class then could be designed to be inherited from.
class Task {
public:
virtual int func1(void) = 0;
virtual int func2(void) = 0;
};
// v~~~~v probably dllimport in the header you ship
extern "C" __declspec(dllexport) Task * APIENTRY newTask();
class TaskWrapper {
public:
TaskWrapper() : m_ptr( newTask() ) {}
virtual ~TaskWrapper() { deleteTask(m_ptr); }
virtual int func1(void) { m_ptr->func1(); }
virtual int func2(void) { m_ptr->func2(); }
protected: // implementation omitted for brevity
TaskWrapper(TaskWrapper const&);
TaskWrapper(TaskWrapper&&);
TaskWrapper& operator= (TaskWrapper const&);
TaskWrapper& operator= (TaskWrapper&&);
private:
Task* m_ptr; // preferably a unique_ptr
};
You could also let TaskWrapper derive from Task.
If I understand the question correctly, you want ApplImp to derive from TaskImp, and call into TaskImpl member implementations as needed, using standard C++ syntax..
You can't do that directly because the application and DLL are linked separately and have no compile-time knowledge of each other. The application doesn't know about TaskImpl at compile time, thus the compiler cannot derive from it and cannot create a Vtable that may be a combination of funcitons from application and DLL.
You chould compose the objects, i.e. create an instance of TaskImp inside ApplImp and delegate all functions to the TaskImp instance inside of ApplImp. That's inconvenient in many cases.
A more convenient way is to export the implementation of TaskImpl from the DLL: declare the whole class as __dllexport. Unfortunately, that's the least portable way to do it and in a large project, it may lead to a huge dll export section with 10000 C++-name-mangled entries. But you might be able to use TaskImpl as a base class in other DLLs or the application.
Btw, this won't compile because ApplImp is derived from Task, and Task* cannot be cast implicitly to ApplImpl.
ApplImp * aNewTask = static_cast(newTask());

Is it possible to keep a naked class definition without declaring it's methods?

Prior to refactoring my previous question, which I believe was a little bit off...
The title pretty much asks my question.
How can I keep a class definition on it's own without giving it methods & producing the error below?
The reason for this is because I want to create an object in a separate DLL (which contains the methods), but only return a reference pointer to my main program.
This is explicit exporting by the way.
Error 1 error LNK2001: unresolved external symbol "public: int
__thiscall ObjTest::getValue(void)" (?getValue#ObjTest##QAEHXZ)
class ObjTest
{
private:
int x;
public:
int getValue();
};
Since you need to load the .dll with LoadLibrary(), you can expose a pure virtual class, and have the .dll return a sub class of it:
You separate them in two files:
File ObjTest.h:
class ObjTest
{
public:
virtual int getValue() = 0;
};
ObjTest *CreateObjTest();
File ObjTest.cpp:
#include "ObjTest.h"
class ObjTestImpl : public ObjTest
{
int x;
public:
virtual int getValue();
};
int ObjTestImpl::getValue()
{
return x;
}
ObjTest *CreateObjTest()
{
return new ObjTestImpl();
}
You compile ObjTest.cpp and create a .dll out of it. Your main executable program will need to LoadLibrary() your .dll, use GetProcAddress() to extract the CreateObjTest as a function pointer and call it to return a new ObjTest .
(You might have to create a DeleteObjTest() function too - if your main executable and .dll end up with a different CRT, they'll have different heaps, so you need to call into the .dll instead of just doing delete myObj.)
The other approach is to wrap everying in a C API, and just pass opaque handles to C functions across the .dll instead of dealing with C++ objects.
You are confusing definition and implementation. You have the method defined but not implemented. Hence, the compiler compiles the code without error, as the method is defined, the linker creates an error as there is no implementation for the method (undefined symbol).
The DevStudio compiler does let you import classes from DLLs into an application:-
class __declspec (dllimport) ClassName
{
// members, etc
}
and in the DLL source, change the 'dllimport' to 'dllexport'.
See this MSDN article for more information.
If you want to hide the data members and the private methods then you'd need to look into the pimpl idiom.

Interfaces, hiding concrete implementation details in C++

I have a question regarding hidinging interface details in C++ libraries. The problem is ilustrated with the following example:
Let's say w have a class called ISystem which exposes methods like Init, Run, Tick, Shutdown, GetXXXSubSystem.
Where X are pointers various interfaces like: ISoundSystem, IInputSystem
We also have concrete implementations of ISystem like:
Win32System, OSXSystem etc.
These specific implementations use a pimpl idiom to hide internals
and for example Win32System instantiates Win32RawInputSystem
as input system manager.
All such managers do have their own Init, Run, Tick and Shutdown methods
which are not part of the interface (only concrete implementation) and these are run and managed by the concrete system implementation.
The user calling GetXXXSubSystem gets interface pointer without those methods (Init etc..) but
still he could cast the pointer he gets to concrete implementation
and trigger methods like Init Run Tick etc. which he shouldn't have access to.
The question is, is it possible to hide the concrete class somehow? I tried to make those methods
protected in the concrete implementations and template the class on type which would eventually be friend but this appears to be prohobited and existing hacks do not work with VC11.
The only way I can think of right know is to transfer the concrete implementation declaration from header
into the cpp file of Win32System class but I see ahuge drawback of doing this (even not sure if this would work), because this way each subsystem
would have to be also part of this cpp file and it would become a maintainability nightmare.
Another solution I am thinking about is using factory method like
(RawInput.h)
IInputSystem* CreateRawInputSystem();
(RawInput.cpp)
class RawInput : public IInputSystem {}; ...
and move definition of the class to cpp file but then, how I would acces this type from other parts of my library (ie in Win32System impl)?
Is it possible to include .cpp files form other .cpp files?
Thanks in advance for any tips.
If you're developing a library here, then you can simply choose not to export the header files of the concrete classes that you do not want to expose. You cannot cast to a class of which you do not have a definition.
Example :
MyProjectFolder/Src/Export/ISystem.h
#ifndef ISYSTEM_H
#define ISYSTEM_H
#include "IInputSystem.h"
class ISystem
{
public:
virtual ~ISystem() {};
virtual void Run()=0;
virtual IInputSystem* GetInputSystem()=0;
};
#endif
MyProjectFolder/Src/Export/IInputSystem.h
#ifndef IINPUTSYSTEM_H
#define IINPUTSYSTEM_H
class IInputSystem
{
public:
virtual ~IInputSystem() {};
virtual void Foo()=0;
virtual void Bar()=0;
};
#endif
MyProjectFolder/Src/Export/Win32System.h
#ifndef WIN32SYSTEM_H
#define WIN32SYSTEM_H
#include "ISystem.h"
class Win32System : public ISystem
{
public:
Win32System();
virtual void Run();
virtual IInputSystem* GetInputSystem();
private:
struct impl;
impl* m_pImpl;
};
#endif
MyProjectFolder/Src/Win32RawInputSystem.h
#ifndef WIN32RAWINPUTSYSTEM_H
#define WIN32RAWINPUTSYSTEM_H
#include "IInputSystem.h"
class Win32RawInputSystem : public IInputSystem
{
public:
virtual void Foo();
virtual void Bar();
virtual void Run(); // you do not want to expose that function
};
#endif
MyProjectFolder/Src/Win32System.cpp
#include "Win32System.h"
#include "Win32RawInputSystem.h"
struct Win32System::impl
{
Win32RawInputSystem inputSys;
};
Win32System::Win32System()
: m_pImpl(new impl)
{
}
void Win32System::Run()
{ // run run run
}
IInputSystem* Win32System::GetInputSystem()
{
return &m_pImpl->inputSys;
}
So when building your project its include search path is not only Src/ but also Src/Export/. From within your library project you can use all classes, including Win32RawInputSystem. When deploying your library you only give away those headers that reside in the Src/Export/ folder. Clients can still use the library, but they can never cast IInputSystem* to Win32RawInputSystem* because they do not have that header. Therefore the users of that library can invoke Foo() and Bar() on the IInputSystem*, but they'll never be able to invoke Run().