Calling the destructor of static objects in a shared library - c++

I have implemented singleton of Meyers and four function to work with it. For example:
//A.h
class A
{
private:
Device d;
public:
A(){//...}
~A(){d.release();}
}
My class singleton Meyers
//Controller.h
class Controlle
{
private:
//some members
A m_member;
Controller();
Controller(const Controller&);
Controller& operator=(const Controller&);
public:
static Controller& GetInstance()
{
static Controller instance;
return instance;
}
}
And interface for working the class of Controller
extern "C" API Result InitDevice(const ParamsDevice* param);
extern "C" API Result InitAlgorithm(const ParamAlgorithm* param);
extern "C" API Result Operation_1();
extern "C" API Result Operation_2();
I build the library and get the Controller.dll and Controller.lib files. Library is shared lib.
Then I create a program where Controller.dll is used (implicit). Runtime library exception is thrown after program termination. I compiled the library in debug to check where the exception is thrown from.
I am getting the exception from comip.h file from method Release() class
template<typename _IIID> class _com_ptr_t
{
public:
// Declare interface type so that the type may be available outside
// the scope of this template.
//
typedef _IIID ThisIIID;
typedef typename _IIID::Interface Interface;
........
// Provides error-checking Release()ing of this interface.
//
void Release()
{
if (m_pInterface == NULL) {
_com_issue_error(E_POINTER);
}
else {
m_pInterface->Release();
m_pInterface = NULL;
}
}
}
I think that when the program terminates, the resources of static objects that are used in the library are incorrectly released. If I replace the singelton Meyers with a classic singelton and create methods for explicitly freeing up the memory of a static pointer, then everything works well. Could you help me explain this effect?
I think there is an answer to my question, but it is not complete for me and I cannot understand
https://stackoverflow.com/a/50644725/13970084
P.S. Sorry for my English. English isn't my native language.

Related

Why does an exported dll class give me memory access violation in client program? [SOLVED]

So I've got this interface class that I include, both in the dll and the client project
// InterfaceClass.h
#pragma once
class InterfaceClass
{
public:
virtual void Update() = 0;
};
This is the dll class that calls one of its own methods inside update
// DLLClassThatDoesSomething.cpp
#include "InterfaceClass.h"
#include <iostream>
#include <string>
class __declspec(dllexport) DLLClass : public InterfaceClass
{
public:
void Update()
{
std::cout << this->GetString();
}
std::string& GetString()
{
std::string thestring = "bruhmoment";
return thestring;
}
};
extern "C"
{
__declspec(dllexport) InterfaceClass* CreateInstance()
{
return new DLLClass();
}
}
And this is the "Client" project
// main.cpp
#include "InterfaceClass.h"
#include <Windows.h>
typedef InterfaceClass* (__cdecl *Class) ();
int main()
{
HINSTANCE dll = LoadLibrary(L"DLLClass.dll");
Class klass = (Class)GetProcAddress(dll, "CreateInstance");
InterfaceClass* IKlass = klass();
IKlass->Update();
FreeLibrary(dll);
return 0;
}
The moment I call IKlass->Update() I get an exception for Access Memory Violation because of the DLLClass calling its own method.
I haven't tried anything since I barely know how to load a DLL on runtime and I've used this nifty tutorial
How can I let it call the method and not get thrown an exception? I'm trying to let ppl that will create mods for my game create their own mods with their custom classes for bosses, mobs and etc. in DLLs.
EDIT:
Turns out it was a syntax mistake on my end. Instead of return new DLLClass;, it had to be return new DLLClass();. After fixing it, it works as intended.
You return a reference to a local variable thestring, and by the time you try to access it in
std::cout << this->GetString(), referenced data is already destroyed. In fact, it is destroyed right after the end of enclosing scope of compound statement where the variable was declared.
It may "appear" to work sometimes due to the stack not being overwritten yet, but eventually it will fail miserably like it did in your case. This triggers UB (undefined behavior).

Shared object depending on symbol in code dynamically linking it?

I have a shared object my_lib.cc that defines in its header a class together with a factory function:
extern Foo* GetFoo():
class Foo {
public:
Foo() {}
virtual ~Foo() {}
};
Now I would like application that uses the library, main.cc, to contain:
#include "my_lib.h"
class Bar : public Foo {
// ...
};
Foo* GetFoo() {
return new Bar();
}
The point being that when the code inside the shared object needs to create a Foo it will call the method provided by the application dynamically linking it. Is this possible to do? Typically, an application depends on symbols provided by shared objects, but is it possible to have a shared object depend on a symbol in the binary that dynamically loads it?
Dynamic linking goes one way, from the user of the library → to the library.
Callbacks from the library to the user are usually done through a function pointer:
In my_lib.cc:
Foo* (*MakeFoo)();
void setFooFactory(Foo* (*pMakeFoo)()) {
MakeFoo = pMakeFoo;
}
Then in main.cc:
Foo* MakeBar() {
return new Bar();
}
int main() {
// load my_lib ...
setFooFactory(MakeBar);
// . . .
}
You can also wrap MakeFoo() into a factory class and use the C++ virtual function mechanism. I'm just demonstrating the main idea.

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.

Destructor of static instance in second dll not being called

Situation
External library (LibraryExternal) that I cannot change calls LoadLibrary on LibraryA. After it is succesfully loaded, it calls an exported function AExport which returns a pointer to ClassA, which is a static instance. Before AExport returns, it too loads a library via LoadLibrary, called LibraryB. After succesfull load, it calls an exported function BExport which in turn returns a pointer to a static instance ClassB.
IMPORTANT
LibraryA is a c++ dll compiled with vs2012 xp tools and LibraryB is a c++/cli dll also compiled with vs2012 xp tools.
All libraries share some other libraries which only define what ClassA and ClassB need to derive from, in order to make sense of the pointers returned by AExport and BExport. They are nothing more than stubs and do not matter in this question (Only pure virtual functions, no fields and nothing being done in ctor/dtor).
Result
When LibraryExternal gets unloaded via program exit, it calls FreeLibrary on LibraryA. This succesfully calls the destructor of ClassA which in turn frees the library LibraryB. But the destructor of ClassB is never run somehow.
Desired Result
Have ClassB destructor run
ClassA.h
#include <StubA.h>
class StubB;
class ClassA: public StubA
{
public:
ClassA();
~ClassA();
bool Initialize();
static ClassA &GetInstance()
{
static ClassA INSTANCE;
return INSTANCE;
}
private:
ClassA(ClassA const &);
void operator=(ClassA const&);
HMODULE wrapperModule;
StubB *wrapperPlugin;
};
ClassA.cpp
#include "ClassA.h"
#include <Windows.h>
// typedef WrapperPlugin *(*WrapperPluginInitType) (); This is normally in shared library
static const wchar_t *WRAPPER_MODULE_NAME = L"LibraryB.dll";
static const char *WRAPPER_MODULE_INIT_FUNCTION_NAME = "BExport";
ClassA::ClassA() :
wrapperModule(NULL),
wrapperPlugin(NULL)
{
}
ClassA::~ClassA()
{
if (this->wrapperModule != NULL)
{
FreeLibrary(this->wrapperModule);
}
}
bool CSharpBridge::Initialize()
{
this->wrapperModule = LoadLibraryW(WRAPPER_MODULE_NAME);
if (this->wrapperModule == NULL)
{
return false;
}
WrapperPluginInitType wrapperPluginInit = reinterpret_cast<WrapperPluginInitType>(GetProcAddress(this->wrapperModule, WRAPPER_MODULE_INIT_FUNCTION_NAME));
if (wrapperPluginInit == NULL)
{
return false;
}
this->wrapperPlugin = wrapperPluginInit();
if (this->wrapperPlugin == NULL)
{
return false;
}
return true;
}
extern "C"
{
__declspec(ddlexport) StubA *AExport()
{
if (!ClassA::GetInstance().Initialize())
{
return NULL;
}
return &ClassA::GetInstance();
}
}
ClassB.h
#include <StubB.h>
class ClassB : public StubB
{
public:
ClassB ();
~ClassB ();
static ClassB &GetInstance()
{
static ClassB INSTANCE;
return INSTANCE;
}
private:
ClassB (ClassB const &);
void operator=(ClassB const&);
};
ClassB.cpp
#include "ClassB.h"
#include <Windows.h>
#include <iostream>
#include <fstream>
ClassB::ClassB()
{
std::ofstream myfile;
myfile.open("C:\\Users\\USERNAME\\Desktop\\test1.txt");
myfile << "ClassB::ClassB\r\n";
myfile.close();
}
ClassB::~ClassB()
{
std::ofstream myfile;
myfile.open("C:\\Users\\USERNAME\\Desktop\\test3.txt");
myfile << "ClassB::~ClassB\r\n";
myfile.close();
}
extern "C"
{
__declspec(dllexport) StubB *WrapperInit()
{
std::ofstream myfile;
myfile.open("C:\\Users\\USERNAME\\Desktop\\test2.txt");
myfile << "WrapperInit\r\n";
myfile.close();
return &ClassB::GetInstance();
}
}
Now I know with 100% certainty that ClassA ctor/dtor are called due to some LibraryExternal functions which give me some textual confirmation. And I do seem to be getting test1.txt and test2.txt generated. But NOT test3.txt.
After this I still need to create a managed reference to LibraryC which is a C# dll and 'destruct' that too when ClassB is being destructed.
It appears that you cannot use FreeLibrary on a library that is managed from an unmanaged library. Since the managed library will start the AppDomain for which the unmanaged library knows nothing about. The AppDomain keeps the library alive and therefor the destructor was never ran. See this answer.
Calling something from unmanaged to managed will still require some special attention since in not doing so will result in an exception: 0xC0020001: The string binding is invalid ! See this. What I did to fix the issue was having a static instance at ClassB scope and initializing it with the new operator in ClassB::GetInstance. Otherwise it would not be initialized at all. I then made a function ClassB::CleanUp in which I delete it. It is however important to mark the entire class (both header and source file) unmanaged with #pragma managed(push, off) and #pragma managed(pop).
To still be able to call managed methods/classes you have to make a function in the source file that has been surrounded with #pragma managed(push, on) and #pragma managed(pop). You can then call this function from the unmanaged class. This still seems strange to me, since that function is managed too?

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());