Here's my scenario:
main.cpp
#include <Windows.h>
#include <functional>
std::function<void()> OnPrepare;
int WINAPI WinMain(HINSTANCE inst, HINSTANCE preInst, TCHAR*, int) {
if (OnPrepare) {
OnPrepare();
}
return 0;
}
other.cpp
#define _AFXDLL
#include <afx.h> // TRACE
#include <functional>
extern std::function<void()> OnPrepare;
class Init {
public:
Init() {
OnPrepare = []() {
TRACE("hello, world!\n");
};
}
};
Init g_init;
This code does not work in a Win32 application, but works well in a Console application. I don't know why. Can anyone point out what's wrong with my code? If I can't do it like this, is there a better way?
EDIT:
OnPrepare is always null in a Win32 application, so no "hello, world" will appear.
The code for constructingg_init modifies OnPrepare. This is, of course, only legal if OnPrepare has already been constructed. But what if g_init is constructed before OnPrepare? Then you'll be modifying an object that hasn't been constructed yet and then later constructing an object you've already modified. Ouch. Doing real work in the constructors of static objects is never a good idea.
It's not clear what your outer problem is, but this code isn't a good way to solve it. An ugly workaround is to replace your global std::function with a global function that returns a reference to a function static std::function and use that. That ensures the object is constructed before being assigned to.
std::function<void()>& getOnPrepare()
{
static std::function<void()> OnPrepare;
return OnPrepare;
}
Then the constructor of Init can call getOnPrepare, ensuring that OnPrepare is constructed before it's assigned to:
Init() {
getOnPrepare() = []() {
TRACE("hello, world!\n");
};
Related
I am using VS2019
Trying to call a thread in DLL. to run two executables simultaneously with detach
following threads worked when I Run a normal c++ program
I get error
Error C3867 'myClass::runexeone': non-standard syntax; use '&' to create a pointer to member myGateway C:\Users\user\Downloads\Demo\myGateway\myplugin.cpp 21
plugin header
#include <windows.h>
#include <iostream>
#include <thread>
#define MYPLUGIN_EXPORT __declspec(dllexport)
extern "C"
{
MYPLUGIN_EXPORT void WINAPI OnStart();
}
pluging.cpp
#include "plugin.h"
using namespace std;
class myClass
{
public:
myClass()
{
}
~myClass()
{
}
void onStart()
{
std::thread(runexeone).detach();
std::thread(runexetwo).detach();
}
void runexeone()
{
int exerunpne = system("cmd /C \"%MY_ROOT%\\bin\\Mytest.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
void runexetwo()
{
int exeruntwo = system("cmd /C \"%MY_ROOT%\\bin\\Mytest_2.exe\" -ORBEndpoint iiop://localhost:12345 -d");
}
};
myClass& getmyclass()
{
static myClass myclass;
return myclass;
}
MYPLUGIN_EXPORT void WINAPI OnStart()
{
getmyClass().onStart();
}
The problem is that runexeone is an unqualified name of a member function, and std::thread needs something executable. runexeone isn't. VC++ tries to guess from context what you mean, but the suggestion isn't enough. Even if you had written &myClass::runexeone, it still wouldn't have worked, because myClass::runexeone also needs a this pointer. You can fix the latter problem by making it static.
Compiler suggestions work best when there's just one problem.
As MSalters already mentioned, you provided the wrong data type for the functor for std::thread. If you cannot make the method static (which you can actually at least for the current state of your code, but to let this not be unstated here), you can do this
void onStart()
{
std::thread(std::bind(&myClass::runexeone, this)).detach();
}
But be careful about the lifetime/existence of your object/this!
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).
In class Foo I have two methods, assign_handler() and call_handler().
The actual handler code is in the main.cpp which is do_this(). do_this() uses the some global variables in main.cpp,
I think Foo has to have a function pointer as member which will be assigned in assign_handler() which is what I did. However I'm having trouble invoking assign_handler() i.e. calling do_this(), from call_handler().
Note: call_handler() itself is call by a sigaction in Foo.
EDIT: I tried producing a MCVE as suggested in the comments. I've used gedit to create the files and compile it using g++ in command line. The code works. However in my Eclipse project I get the errors shown in inline comments of the code.
MCVE:
//Foo.h
class Foo{
public:
void (*funptr)(void);
void call_handler();
void assign_handler (void(*func1)(void));
Foo(){};
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
funptr();//error: invalid use of member Foo::funptr in static member function; from this location
//or
//this->funptr();//error: 'this' is unavailable for static member functions
}
//main.cpp
#include <iostream>
#include "Foo.h"
using namespace std;
void do_this(void);
int main(void){
Foo foo;
foo.assign_handler(do_this);
foo.call_handler(); //this won't be called explicitly, it is assigned as a handler for a sigaction
int x;
cin>>x;
}
void do_this(void){
cout<<"done"<<endl;
}
I'll divide my answer in two parts. First I'll attempt to answer your question, then I'll attempt to tell you what you actually want to do.
Your question is how to assign a function pointer to a member variable and then call it from a static member function. Since the function pointer is a member of the class you will also require a pointer to the class in order to call the function pointer. A way of achieving this is to add a static member to your class that holds a pointer to the (single) instance of your class. Since you indicated that you will be using this as a signal handler, you won't want to use multiple handlers anyway.
So, something like this:
//Foo.h
class Foo{
public:
static void call_handler();
void assign_handler (void(*func1)(void));
Foo() {
ms_instance = this;
};
private:
void (*funptr)(void);
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::assign_handler(void(*func1)(void)){
funptr = func1;
}
void Foo::call_handler(){
ms_instance->funptr();
}
A more general way would be to store a function object:
//Foo.h
#include <functional>
#include <utility>
class Foo{
public:
static void call_handler();
template<typename func>
void assign_handler (func&& handler)
{
m_handler = std::forward(handler);
}
Foo() {
ms_instance = this;
};
private:
std::function<void(void)> m_handler;
static Foo *ms_instance;
};
//Foo.cpp
#include "Foo.h"
void Foo::call_handler(){
ms_instance->m_handler();
}
This way you can assign lots of different stuff as the handler:
// Function pointers
foo.assign_handler(do_this);
// Lambdas
foo.assign_handler([]() { /* do something */ });
// Binds - you should probably prefer lambdas...
foo.assign_handler(std::bind(&MyClass::member_func, &myObj));
Now what you actually want to do when you are going to handle a signal is a bit more complicated. Remember that signal handlers can only call certain functions (async-signal-safe functions) - otherwise things may get ugly. Therefore there is a common trick that you should perform called the self pipe trick. Essentially you should have a signal handler that receives the signal, but only calls write on a pipe with the signal number as the data to send. Then you have another place in your code that calls select on the pipe and then read to read the signal number. You then call the appropriate handler function which is then allowed to do whatever you like.
An example of this is here: http://man7.org/tlpi/code/online/book/altio/self_pipe.c.html
Be aware that it can be slightly tricky to get this right in a cross-platform manner, especially if multithreaded.
While doing some random-ish, weird-ish things to understand a little bit more C++ (just to say I'm still a newbie), I came across something I can't properly understand : I'm currently using SFML which provides a few methods to create and manage a window, namely this method to close it: void sf::RenderWindow::close(). It doesn't take any argument, and it can't be called directly but through an instantiated object.
sf::RenderWindow::close(); // error
My problem is the following code :
sf::RenderWindow window(sf::VideoMode(800, 600), "test"); // added after edit
const std::function <void(sf::RenderWindow &)> callback(sf::RenderWindow::close);
// callback();
callback(window); // closes the window
I'm not sure to understand what's happening here as I'm not using any object... even anonymous at first sight... I guess...
If someone can enlighten me, I'd really appreciate it.
Thanks you.
Edit:
My mistake, yes there's an object.
#include <iostream>
#include <functional>
#include <SFML/Graphics.hpp>
int main()
{
sf::RenderWindow window(sf::VideoMode(800, 600), "test");
const std::function <void(sf::RenderWindow &)> call(sf::RenderWindow::close);
call(window);
return 0;
}
Actually, I understand this as if it were sf::RenderWindow::close(window), similarly to metatables in lua I suppose.
It's linked to the concept of Callable:
Since the stored target of the std::function (i.e. sf::RenderWindow::close) is a pointer to member function and the first argument (i.e. window) is a (reference to) an object of type RenderWindow, then the invocation of the function object is equivalent to window.close().
You could also have written something along those lines:
std::function<void(sf::RenderWindow*)> call = &sf::RenderWindow::close;
call(&window);
Below a code sample that doesn't involve SFML:
#include <iostream>
#include <functional>
class Window {
public:
void close() {std::cout << "close" << std::endl; }
};
int main(int argc, const char * argv[]) {
Window w;
std::function<void(Window&)> f = &Window::close;
f(w);
std::function<void(Window*)> g = &Window::close;
g(&w);
return 0;
}
I would like to know if there was a way to declare a class before a function, and then initialize it inside of a function, something like this:
Application.h:
class Application
{
Application(HWND hwnd);
~Application() {}
};
Main.cpp:
#include "Application.h"
#include <Windows.h>
Application App;
int main()
{
App(hwnd);
return 0;
}
Application *pApp;
int main()
{
pApp = new Application(hwnd);
//use pApp
delete pApp;
return 0;
}
Using a pointer is pretty much the only way to do what you want to do.
You cannot initialize a global object inside a function, the constructor of the object will be called some time before the main function of the program is called. This is very bad, it involves the thing called static initialization fiasco and you want to avoid it. Try to search for singleton pattern implementation in C++, that's what you need probably.
In C++ the constructor for an object is called when the storage for it is allocated, you cannot call the constructor later like you tried to do.
You might consider not defining a constructor, and using a separate member function, for example init, to initialize your App object.
Application.h:
class Application
{
public:
void init(HWND hwnd);
};
Main.cpp:
#include "Application.h"
#include <Windows.h>
Application App;
int main()
{
App.init(hwnd);
return 0;
}