i am working with DLLs and i am new to it.
I am trying to load derived class inherited from my Interface
class IModule{
public:
virtual ~IModule(); // <= important!
vector<String> getFunctions();
protected:
vector<String> mFunctions;
};
class DllModule : public IModule {
public:
DllModule() {
this->mFunctions.push_back("Algorythm");
};
private:
int test;
};
and here I want send pointer to my application
extern "C" {
IModule* CreateModule() {
// call the constructor of the actual implementation
IModule * module = new DllModule;
// return the created function
return module;
}
}
In my application after I load it
f_GetFunctions funci = (f_GetFunctions)GetProcAddress(hGetProcIDDLL, "CreateModule");
if (!funci) {
std::cout << "Could not locate function CreateModule" << std::endl;
//return EXIT_FAILURE;
return nullptr;
}
IModule* module = funci();
I expect the mFunction populated, but its like new instance of IModule instead of DllModule loaded from DLL. All I want is loop at mFunctions and populate my combobox in QT_App.
Can somebody help me? What's wrong with my expectations?
Thank you very much.
(Everything is done in Windows10)
Edit1: Changed types to minimal (sorry for that)
Function => String
Edit2: I completly forgot about assigning pointer
I was able to circumvent my problem.
I used QLibrary.Load() instead of LoadLibraryA and it did exactly what i wanted.
Related
I think only the static method can do the following thing, but it can works.
can anybody tell me how it works? what's the principle behind this thing.
#include <iostream>
using namespace std;
class Parent {
protected:
unsigned char* buf;
unsigned int bufLenght;
public:
void Setup()
{
buf = nullptr;
bufLenght = 0;
cout << "in Parent class Setup()" << endl;
}
virtual void TearDown()
{
delete[] buf;
}
};
class Child : public Parent{
public:
virtual void Setup()
{
Parent::Setup(); // access Parent method without a parent's object?
cout << "in Child class Setup()" << endl;
}
};
int main(int argc, char const *argv[])
{
Child co;
co.Setup();
return 0;
}
run this code, the result is :
in Parent class Setup()
in Child class Setup()
I find the answer here:
How to call a parent class function from derived class function?
and in thinking in c++, I also find the same description:
However, when you’re redefining a function, you may still want to
call the base-class version. If, inside set( ), you simply call set( )
you’ll get the local version of the function – a recursive function
call. To call the base-class version, you must explicitly name the
base class using the scope resolution operator.
Each Child object is built on top of a Parent object. Whenever you have a Child you also have a Parent.
I can't seem to understand what you're trying to achieve. It appears that you've omitted the 'virtual' keyword on the base class method you're trying to override and hence receiving errors from the compiler.
Although your question is fairly unclear, here is my best attempt at demonstrating how to implement polymorphism in C++:
class A {
protected:
// You will not be able to access this in the
// other class unless you explicitly declare it as
// a 'friend' class.
int m_ProtectedVariable;
public:
// Let's define a virtual function that we can
// override in another class.
virtual void ClassMethod( ) {
printf( "[A::ClassMethod] Called!\n" );
}
}
class B : public A {
public:
// There is no need for the virtual/override keywords
// if you are overloading the function which is already defined
// in another class as 'virtual'. I prefer to keep them for
// pedantic reasons.
/* virtual */ void ClassMethod( ) /* override */ {
//
printf( "[B::ClassMethod] Called!\n" );
// Since the function is a virtual, we can always
// call the base class function.
A::ClassMethod( /* ... */ );
}
}
Hopefully you find this helpful in whatever you're trying to achieve :-)
EDIT: In your particular scenario, where you're supposed to allocate a buffer when you need it and destroy it afterwards - why are you not making use of the class constructor/destructor functionality?
It would be far more intuitive to let the compiler decide when to manage memory (in this case) as it will happen automatically once your object goes out of scope.
I'm currently working on a game engine which implements an architecture based on frameworks.
These frameworks are dynamically loaded into the engine through the using of .so libraries.
To illustrate the frameworks usage, here is a little picture:
Engine/Frameworks interactions
(please, note that the engine also knows about the FrameworkTpl and SpecificFrameworkTpl types)
As we can see, the specificFrameworkImplementation class is compiled as a shared library (.so) and inherit from specificFrameworkTpl which itself inherit from FrameworkTpl.
Once compiled, the library is loaded into the engine at runtime and an instance of the framework is retrieved as a FrameworkTpl.
At this time if I call a FrameworkTpl method, it will works like a charm (which is pretty obvious yes...).
Neverless, if I try to down cast this instance to a specificFrameworkTpl with the help of a dynamic_cast, it will return a nullptr.
Through my research (which have last for about one week while reading mans pages and StackOverflow answers), I saw peoples talking about flags to give to the dlopen function such as RTLD_NOW or to remove like RTLD_LOCAL in favor of RTLD_GLOBAL, but none of them has worked for me, same thing for g++ flags (-rdynamic).
The code:
Here is an example with GuiFrameworkTpl as specificFrameworkTpl
and FrameworkUI for specificFrameworkImplementation.
FrameworkTpl
class FrameworkTpl
{
protected:
std::string _name;
public:
FrameworkTpl(const std::string &name):
_name(name)
{
}
virtual ~FrameworkTpl(void)
{
}
public:
virtual std::string getName(void) const
{
return (this->_name);
}
};
GuiFrameworkTpl
class GuiFrameworkTpl : public FrameworkTpl
{
public:
GuiFrameworkTpl(const std::string & name) :
FrameworkTpl(name)
{
}
virtual ~GuiFrameworkTpl(void)
{
}
virtual void displaySquare(int x, int y, int size) = 0;
};
FrameworkUI
class FrameworkUI : public GuiFrameworkTpl
{
public:
FrameworkUI();
~FrameworkUI();
public:
void displaySquare(int x, int y, int size);
};
extern "C"
{
FrameworkUI* CObject()
{
return (new FrameworkUI);
}
void DObject(FrameworkUI* obj)
{
delete obj;
}
}
App that uses the library and cast stuff from it:
(Here, the Xxx from the previous classes is used as "Gui")
GuiFrameworkTpl* GUISystem::cast_f(const std::shared_ptr<FrameworkTpl>& src)
{
auto ptr = src.get();
Log::print(ptr);
if (!ptr) return nullptr;
Log::inform(ptr->getName());
auto dst = dynamic_cast<GuiFrameworkTpl*>(ptr);
Log::print(dst);
return dst;
}
What I should have:
When I load my library and call CObject() it should create an instance of FrameworkUI which I get in a FrameworkTpl, then I would just have to dynamic_cast it as a GuiFrameworkTpl in order to access particular method.
What I really have:
When I load my library and call CObject() it creates an instance of FrameworkUI which I store in a FrameworkTpl (btw, I can call the getName() method successfully, so the instance is valid). But when I try to down cast it to GuiFrameworkTpl, it gives me a nullptr.
The last function print this:
0xc0c200
[INFO]: FrameworkUI
0
If anyone has some clue about how to solve this problem, I would be very grateful,
Thanks in advance
I was looking around the Notepad++ source code on GitHub recently, and came across a method call like this:
Window::init(hInst, parent);
I searched for the function it was referencing to, and came across a Window class- but the init function was marked virtual, so clearly it was non-static. Thinking I made a mistake, I checked the entire header to make sure there was no static overload of init, and I made sure there was no Window.cpp file. There isn't.
After poking around the source for 15 more minutes, I gave in and git cloned the repo locally so I could open it in Visual Studio. The first thing I did was to build just to make sure this wasn't an accidental merge on behalf of the project developers- the build succeeded.
The next steps I took:
I opened the the file calling Window::init and clicked Go To Declaration on Window. It takes me to the Window class.
I clicked Go To Declaration on the init function. It points me to the signature of the virtual method.
I copy and paste the Window.h file into an entirely new header and replace all references of Window with Foo. When I type in Foo::init, the compiler complains that 'a nonstatic member reference must be relative to a specific object'.
TL;DR: Somehow, the Notepad++ source code calls a non-static method statically, and this builds. Doesn't work with any other class. Proof here and here.
I have spent 2 hours staring at this, but I still don't see how it's possible. Am I missing something?
No, it's not calling a static function. It's just calling the base class's version of init(). Basically, in tClassName::f, you are asking "I want to call that specific version of the virtual function f() in class tClassName".
Generally, it's pretty common to call the base class's counterpart of a virtual function in the derived class. E.g., the factory method pattern:
#include "tObject.h"
#include "tObject1.h" // public inheritance from tObject
#include "tObject2.h" // public inheritance from tObject
#include "tObject3.h" // public inheritance from tObject
class BaseFactory
{
public:
// factory method
virtual tNode *createObject(int id)
{
if (id == 1) return new tObject1;
else return new tObject2;
}
};
class DerivedFactory: public BaseFactory
{
public:
virtual tNode *createObject(int id)
{
// Overrides the default behavior only for one type
if (id == 1) return new tObject3;
// Call the default factory method for all other types
else return BaseFactory::createObject(id);
}
};
Am I missing something?
Yes - context. Notepad_plus_Window derives from Window, and the call to Window::init() is inside of the Notepad_plus_Window::init() method:
class Notepad_plus_Window : public Window {
public:
...
void init(HINSTANCE, HWND, const TCHAR *cmdLine, CmdLineParams *cmdLineParams);
...
};
void Notepad_plus_Window::init(HINSTANCE hInst, HWND parent, const TCHAR *cmdLine, CmdLineParams *cmdLineParams)
{
...
Window::init(hInst, parent);
...
}
In this context, Notepad_plus_Window is calling the base class Window version of init().
Maybe this will confuse you less. You're missing context, at no real fault of your own.
You're not seeing the implicit this in the call.
Take the following example:
#include <cstdio>
#include <iostream>
class Foo {
public:
virtual void bar() {
std::cout << "Foo" << std::endl;
}
};
class Bar : public Foo {
public:
virtual void bar() {
std::cout << "Bar" << std::endl;
}
};
int main() {
Bar bar;
bar.bar(); //-> bar
bar.Foo::bar(); //-> foo
Bar *barp = &bar;
barp->bar(); //-> bar
barp->Foo::bar(); //-> foo
return 0;
}
In the above, we can specify the object on which to call a specific method in the class' hierarchy.
It's not a static function. It's calling a function with a specified (class) scope.
By default, init() will match functions within current class scope, if they do exist. that is an implicit this call, equals this->init(),
But with a specified class/namespace prefix, you can explicit call any particular function without dynamic binding. i.e. ::init() will call the init() function within global scope.
the following code may give you a better understanding
#include <iostream>
class A
{
public:
virtual void test()
{
std::cout << "A" << std::endl;
}
};
class B : public A
{
public:
virtual void test()
{
std::cout << "B" << std::endl;
}
};
int main()
{
A* a = new B();
a->A::test();
return 0;
}
I can't find any answer to this question for C++ (for other languages yes) though I've searched for a number of hours. How can I access a Singleton from another class?
Declaration:
#include "Store.h"
Store *store = Store::Instance(); // Singleton
int main()
{
store->GetDepts();
return 0;
}
I want to be able to access it from my Customer Proxy class:
#include "Store.h"
class Cust_Proxy
{
public:
Cust_Proxy(string cust_name)
{
name_ = cust_name;
}
void AddItem(Item item)
{
store->AddItemToShoppingCart(item); // or something, just for example
}
private:
string name_;
ShopCart cart_;
};
I've tried passing it as a parameter but obviously there's no public constructor in the singleton "store":
void AddItem(Store *store)
{
store = Store::Instance();
// Do Stuff;
}
Any help would be greatly appreciated. Thank you.
Instead of
store->AddItemToShoppingCart(item);
use
Store::instance()->AddItemToShoppingCart(item);
You don't need to store the pointer to the singleton in main.cpp or any other function that uses the singleton. Access the singleton by calling Store::instance() whenever you need it.
In main, you can use:
int main()
{
Store::instance()->GetDepts();
return 0;
}
and remove the line
Store *store = Store::Instance(); // Singleton
I am getting linker error in the code below.
If I make the ClientInterface's ClientAPI() function as pure virtual, then the linker error disappears.
What is the reason for this behavior?
// How the interface looks like to the Client
class ClientInterface
{
public:
virtual void ClientAPI();
virtual ~ClientInterface(){}
};
template <class TYPE> //this adaptor class can adapt to any type of legacy application as it is a generic function that uses template parameter to point to any legacy application
class Adaptor : public ClientInterface
{
public:
Adaptor(TYPE *objPtr, void (TYPE:: *fnPtr)())
{
m_objPtr = objPtr;
m_fnPtr = fnPtr;
}
void ClientAPI()
{
/*....
Do the conversion logic reqd to convert the user params into the params expected by your original legacy application...
....*/
(m_objPtr->*m_fnPtr)(); //Would call the method of the legacy application internally
}
~Adaptor()
{
if(m_objPtr)
delete m_objPtr;
}
private:
TYPE *m_objPtr; //You can keep either pointer to the Legacy implementation or derive the Legacy implementation privately by your Adaptor class
void (TYPE:: *m_fnPtr)();
};
//Adaptee classes below..
class LegacyApp1
{
public:
void DoThis()
{
cout<<"Adaptee1 API"<<endl;
}
};
//Execution class where main is defined and i have include the "Adaptor.h"
#include "headers.h"
#include "Adaptor.h"
void Adapter()
{
ClientInterface **interface_ptr = new ClientInterface *[2];
interface_ptr[0] = new Adaptor<LegacyApp1>(new LegacyApp1() , &LegacyApp1::DoThis);
interface_ptr[1] = new Adaptor<LegacyApp2>(new LegacyApp2() , &LegacyApp2::DoThat);
for(int i = 0; i < 2 ; i++)
{
interface_ptr[i]->ClientAPI();
}
}
int main()
{
//Testing();
Adapter();
char ch;
cin>>ch;
return 0;
}
So the correction in the above code is as follows: Just make the following changes to first few lines of the original code.
// How the interface looks like to the Client
class ClientInterface
{
public:
//earlier I forgot to define it, so it was giving linker error as the function is just declared but not defined.
virtual void ClientAPI(){}
virtual ~ClientInterface(){}
};
Thanks.