GLFW keycallback userpointer not carrying data - c++

I'm trying to send data from my application to the GLFW keyCallback where I then access and modify that data. However, nothing I pass in can be accessed or changed without an app crash. What am I doing wrong?
//main.cpp
typedef struct
{
string type, name;
} DebugUsrPtr;
//hot loop
{
DebugUsrPtr myPtr;
myPtr.type = "aaa";
myPtr.name = "bbb";
void *testPtr = &myPtr;
glfwSetWindowUserPointer(myWin, testPtr);
glfwSetKeyCallback(myWin, keyCallback0);
glfwSetWindowUserPointer(myWin, myWin);
}
//input.cpp
void keyCallback0(GLFWwindow *window, int key, int scancode, int action, int mods)
{
auto *myTest = static_cast<DebugUsrPtr*>(glfwGetWindowUserPointer(window));
cout << "name test = " << myTest->name << endl; // ""
myTest->name = "zzzz"; //prints "zzzz" for one frame then appcrash
}

On this line:
glfwSetWindowUserPointer(myWin, myWin);
When you set that, the user pointer will now point to the window structure, not your struct. So when the callback is called (it is called later), it no longer points to your debug structure, but to the windows pointer.
You need to send the pointer to your structure and let it there as long as you think you will need it.
You have another error, the debug structure is destroyed before the callback is called:
{
DebugUsrPtr myPtr;
myPtr.type = "aaa";
myPtr.name = "bbb";
void *testPtr = &myPtr;
glfwSetWindowUserPointer(myWin, testPtr);
glfwSetKeyCallback(myWin, keyCallback0);
glfwSetWindowUserPointer(myWin, myWin);
} // debug structure destroyed here!
So when the callback is called later, it the debugs structure will be freed, and that will lead to undefined behaviour!
For that, I think you should declare your struct in the parent scope of your event loop. Just like this:
DebugUsrPtr myPtr;
// ...
{
glfwSetWindowUserPointer(myWin, &myPtr);
glfwPollEvents(); // the callback will be called here if user press keys!
}
If you're really doing C++, declare your struct like this instead:
struct DebugUsrPtr {
std::string type, name;
};
If you want a different type or a different pointer for each callback, hold them all in a bigger struct:
struct AllPointers {
DebugUsrPtr dbg;
MouseUsrPtr mouse;
// more...
};

Related

storing, parsing through and executing stored member functions

I'm currently working on some code and need to make something like an event handler that I can register explicit events and store them into a vector that I can loop through in my main listen() function. I'm missing something about pointers that I cant pinpoint with docs and a google search and need help figuring out why my compilers asking for a pointer to a member.
I've tried creating a typedef with a member function definition but I have the problem of it not compiling currently with a "non standard syntax, put an & to create a pointer to a member." error.
class Obj {
private:
typedef int (Obj::*Event) (std::vector<std::string> in);
std::vector<Event> events;
int exampleEvent(std::vector<std::string> input);
public:
Obj();
int regEvent(Event ev);
int listen();
}
example event code
int Obj::exampleEvent(std::vector<std::string> input)
{
// heres my app logic
return 0;
}
register events in constructor
Obj::Obj()
{
regEvent(exampleEvent); // exampleEvent: non-standard syntax; use
//'&' to create a pointer to member
}
listen, and add event to vector.
int Obj::regEvent(Event ev)
{
events.push_back(ev);
return 0;
}
// listen for command input
int Obj::listen()
{
// get input
string str;
getline(cin, str);
vector<string> input = split(str, " ");
// loop through events
for (auto ev : events)
{
ev(input); // <-- Term does not evaluate to function taking 1 arg.
}
return 0;
}
Obj::Obj()
{
regEvent(exampleEvent); // exampleEvent: non-standard syntax; use
//'&' to create a pointer to member
}
must be
Obj::Obj()
{
regEvent(&Obj::exampleEvent);
}
and
for (auto ev : events)
{
ev(input); // <-- Term does not evaluate to function taking 1 arg.
}
must be
for (auto ev : events)
{
(this->*ev)(input);
}
Exxpected syntax is:
regEvent(&Obj::exampleEvent);

C++ win32 thread createThread function not passing parameter correctly

So, I have been trying to figure out how c++ multi-threading works and how to apply it to the project I am working on. I am trying to accomplish creating a new thread and running a function on that thread. The function I am trying to run is called SetupInfo and takes an Individual as a single parameter. I have seen examples of this and have tried to implement them, but after multiple attempts I cannot successfully pass the parameter I need into the thread I want the function to run on. Here is what I have come up with:
Here I create a struct to store the pointer to the Individual that I need later on.
struct ThreadData
{
Individual *m_pInd;
ThreadData(Individual pInd) : m_pInd(*pInd) {}
};
Here I create a function that I can call in my program that creates the thread that runs the function SetupThreadFunction which takes a void pointer as a parameter. I am trying to pass the variable data into this function and then cast it back to ThreadData to be able to access the items of the struct.
void SetupThread(Individual input)
{
ThreadData *data = new ThreadData(input);
CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);
delete data;
}
Here I create the function that is passed into the CreateThread function which takes a void pointer and casts it to ThreadData which can then theoretically access the threadData->m_pInd. The same pointer for data above is passed correctly into the SetupThreadFunction. However, m_pInd contains null data and not the pointer to the information that is expected. Why is that?
DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
ThreadData* threadData = (ThreadData*)lpParameter;
SetupInfo(threadData->m_pInd);
return 0;
}
Is there a more correct way to pass a parameter into the new win32 thread I am creating?
The correct pattern is to allocate the object with new, fill in the data (if not done through parameters to new), pass the pointer to the newly-created thread, and let the thread delete the object when it's done with it. You delete the object before you know the thread has even started!
This isn't a multithreading problem; it's a pointer problem.
This line doesn't make sense to me:
ThreadData(Individual pInd) : m_pInd(*pInd) {}
m_pInd is a pointer and yet you're initializing it with *pInd which means you want to dereference pInd, but pInd is not a pointer, let alone a pointer to a pointer. I don't see how this would even compile.
Assuming you actually meant & instead of *, as in:
ThreadData(Individual ind) : m_pInd(&ind) {}
The problem here is that you're creating a pointer to a copy of an Individual on the stack, and that copy goes away upon return from the constructor, so you have a dangling pointer.
Use std::thread.
void ThreadProc(Individual individual);
int main()
{
Individual individual;
std::thread thread(ThreadProc, individual);
thread.join();
return 0;
}
Here's a simple code example to demonstrate the points already discussed.
#include "stdafx.h" // includes <windows.h>, <string> and <iostream>
using std::string;
using std::cout;
class Individual
{
public:
string s;
};
struct ThreadData
{
Individual *m_pInd;
ThreadData(Individual* pInd) : m_pInd(pInd) {}
};
DWORD WINAPI SetupThreadFunction(LPVOID lpParameter)
{
cout << "Hi From Thread\n";
ThreadData* threadData = static_cast<ThreadData*>(lpParameter);
//SetupInfo(threadData->m_pInd);
// do delete here, once its finished with.
delete threadData;
return 0;
}
HANDLE SetupThread(Individual* input)
{
ThreadData *data = new ThreadData(input);
return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE) SetupThreadFunction, data , 0, 0);
}
int _tmain(int argc, _TCHAR* argv[])
{
cout << "Hi\n";
Individual* i = new Individual;
HANDLE h = SetupThread(i);
if(h)
{
WaitForSingleObject(h, INFINITE);
cout << "Done\n";
} else
{
cout << "Couldnt create thread\n";
}
getchar();
delete i;
return 0;
}
Bear in mind also you can use _beginthread as a simpler interface to launch a thread on Win32.

Destructor Called Before Object Goes Out Of Scope

So I've been cleaning up a bit of code, and I noticed that the desctructor of a class was being called directly after the constructer is called. Effectively, the object does nothing. Im pretty sure the object is still in scope, because I can access its members still. In the constructer I've printed out this and in the destructor I've printed out "deleted: " << this. Here is what the output looks like:
x7fff5fbff380
0x7fff5fbff3d0
deleted: 0x7fff5fbff3d0
deleted: 0x7fff5fbff380
0x7fff5fbff280
0x7fff5fbff2d0
deleted: 0x7fff5fbff2d0
deleted: 0x7fff5fbff280
0x7fff5fbff190
0x7fff5fbff1e0
deleted: 0x7fff5fbff1e0
deleted: 0x7fff5fbff190
Obviously, this isn't enough to help solve the problem, so here is some code, involving how the object is created, how it is used and how it is destroyed.
//event listener constructor
EventListener::EventListener(EventTypes typeEvent,EventFunction functionPointer)
{
this->typeEvent = typeEvent;
this->functionPointer = functionPointer;
//add it to the tick handler
this->listenerID = EngineEventDispacher.addEventListener(this);
std::cout << this << std::endl;
}
void EventListener::removeListener()
{
//remove it from the tickHandler
EngineEventDispacher.removeEventListener(this->listenerID);
}
//we add the event listener here
int EventDispatcher::addEventListener(EventListener* listener)
{
EventListeners.push_back(listener);
return (int)EventListeners.size() - 1;
}
//get rid of a listener
void EventDispatcher::removeEventListener(int id)
{
//std::vector<EventListener*>::iterator it;
//it = EventListeners.begin() + id;
//EventListeners.erase(it);
// EventListeners.shrink_to_fit();
//this isnt very memory efficiant, but it is the best solution for the CPU
EventListeners[id] = nullptr;
}
//send an event to all the listeners that can have it
void EventDispatcher::dispatchEvent(EventTypes eventType, Event* event)
{
for (int i = 0; i < EventListeners.size(); i++)
{
//we check if the current listener is subscribed to the event we are calling
if (EventListeners[i] != nullptr)
if (EventListeners[i]->typeEvent == eventType && EventListeners[i]->functionPointer != 0 )
{
//it was subscribed, so we are going to call it
EventListeners[i]->functionPointer(event);
}
}
}
//make sure that we can't call this
EventListener::~EventListener()
{
EngineEventDispacher.removeEventListener(this->listenerID);
std::cout << "deleted: " << this << std::endl;
}
What the classes look like:
//This will recive events
class EventListener
{
//this is what type of event it will repsond to
public:
EventTypes typeEvent;
EventListener(EventTypes typeEvent, EventFunction);
EventListener();
~EventListener();
EventFunction functionPointer;
void removeListener();
private:
int listenerID;
};
//her we define the event dispatcher
class EventDispatcher
{
public:
int addEventListener(EventListener*);
void removeEventListener(int);
void dispatchEvent(EventTypes, Event*);
private:
std::vector<EventListener*>EventListeners;
};
And finally how the event listener is declared and constructed:
class Scene
{
public:
Scene();
std::vector<StaticGeometry>GameObjects;
void addStaticGeometry(StaticGeometry object);
void renderSceneWithCamera(camera cam);
void renderSceneWithCameraAndProgram(camera cam,GLuint program);
void pickObjectFromScene();
void pickObjectFromSceneWithScreenCoords(int x, int y);
int selectedObject;
private:
//listen for the left click
EventListener leftClickEventListener;
void leftClick(Event* eventPtr);
};
Scene::Scene() : leftClickEventListener(EventTypeLeftMouseClick,std::bind(&Scene::leftClick,this,std::placeholders::_1))
{
//default constructor, we just need to make sure that the selected thing is -1
selectedObject = -1;
}
As far as I know, members aren't supposed to call the deconstructor until the parent calls theirs. The Scene class most definitely isn't calling its reconstructor, and thats what really has me puzzled. Everything should be fine, but its not. Nothing I've found says that things should just randomly decide to deconstruct themselves. Any help would be appreciated. Thanks.
Problem:
If you create an object inside a block or function with automatic storage duration, like
{
// ...
EventListener myListener();
// ...
}
the object will be destroyed as soon as execution leaves the block/function, even though it may still be referenced from elsewhere. See also:
Creating an object: with or without `new`
Generally, you should never pass a pointer to an object with such scope anywhere where it might be stored internally.
Solution:
You'll have to explicitly use new if you want your object to live beyond the current block:
{
// ...
EventListener* myListener = new EventListener();
// ...
}
Im pretty sure the object is still in scope, because I can access its
members still.
Beware: A pointer to an object may still seem to be usable even after the object has been (implicitly) destroyed, but dereferencing this pointer is a severe, though not always obvious, bug.

EXEC_BAD_ADDRESS

maybe this is the continuation of this thread,
The program compiles without errors or warnings but when I run it, and the handler function is called, I get EXEC_BAD_ADDRESS
void MainController::show_color_trackbars(int *h, int *s, int *v){
String winName = "HSV Trackbars";
namedWindow(winName, CV_WINDOW_AUTOSIZE);
std::map<String, void*> user_data_h;
user_data_h["Object"] = this; //this is a MainController object
user_data_h["h"] = h;
createTrackbar("trackbar_H", winName, h, 255, trackbar_handler, &user_data_h);
};
void trackbar_handler(int value, void *user_data){//callback for the track bar
std::map <String, void*> *user_data_map;
user_data_map = reinterpret_cast<std::map<String, void *> *>(user_data);
MainController *controller;
controller = reinterpret_cast<MainController *>((*user_data_map)["Object"]);
int *var;
var = reinterpret_cast<int*> ((*user_data_map)["h"]);
//do something with controller and var
};
I am mistaking something when casting? I cannot think of another reason this code is failing.
Thanks in advance
That's because in all probablity user_data_h is a local variable and is already destroyed when trackbar_handler is called. trackbar_handler works on a pointer which is no longer valid!
Please check if it is okay to have user_data_h dynamically allocated and register that pointer with the callback dispatch.

Callback to non-static method

Think of your basic GLUT programs. They simply run from a main method and contain callbacks like `glutMouseFunc(MouseButton) where MouseButton is the name of a method.
What I have done is I have encapsulated the main file into a class, so that MouseButton is no longer a static function but has an instance. But doing this gives me a compilation error :
Error 2 error C3867: 'StartHand::MouseButton': function call missing argument list; use '&StartHand::MouseButton' to create a pointer to member c:\users\angeleyes\documents\visual studio 2008\projects\capstone ver 4\starthand.cpp 388 IK Engine
It is not possible to provide a code sample as the class is quite huge.
I have tried using this->MouseButton but that gives the same error. Can't a pointer to an instance function be given for callback?
As the error message says, you must use &StartHand::MouseButton syntax to get a pointer to a member function (ptmf); this is simply mandated as part of the language.
When using a ptmf, the function you are calling, glutMouseFunc in this case, must also expect to get a ptmf as a callback, otherwise using your non-static MouseButton won't work. Instead, a common technique is for callbacks to work with a user-supplied void* context, which can be the instance pointer—but the library doing the callbacks must explicitly allow this parameter. It's also important to make sure you match the ABI expected by the external library (the handle_mouse function below).
Since glut doesn't allow user-supplied context, you have to use another mechanism: associate your objects with glut's current window. It does provide a way to get the "current window", however, and I've used this to associate a void* with the window. Then you simply need to create a trampoline to do the type conversion and call the method.
Machinery:
#include <map>
int glutGetWindow() { return 0; } // make this example compile and run ##E##
typedef std::pair<void*, void (*)(void*,int,int,int,int)> MouseCallback;
typedef std::map<int, MouseCallback> MouseCallbacks;
MouseCallbacks mouse_callbacks;
extern "C" void handle_mouse(int button, int state, int x, int y) {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) { // should always be true, but possibly not
// if deregistering and events arrive
i->second.second(i->second.first, button, state, x, y);
}
}
void set_mousefunc(
MouseCallback::first_type obj,
MouseCallback::second_type f
) {
assert(obj); // preconditions
assert(f);
mouse_callbacks[glutGetWindow()] = MouseCallback(obj, f);
//glutMouseFunc(handle_mouse); // uncomment in non-example ##E##
handle_mouse(0, 0, 0, 0); // pretend it's triggered immediately ##E##
}
void unset_mousefunc() {
MouseCallbacks::iterator i = mouse_callbacks.find(glutGetWindow());
if (i != mouse_callbacks.end()) {
mouse_callbacks.erase(i);
//glutMouseFunc(0); // uncomment in non-example ##E##
}
}
Example:
#include <iostream>
struct Example {
void MouseButton(int button, int state, int x, int y) {
std::cout << "callback\n";
}
static void MouseButtonCallback(
void* self, int button, int state, int x, int y
) {
static_cast<Example*>(self)->MouseButton(button, state, x, y);
}
};
int main() {
Example obj;
set_mousefunc(&obj, &Example::MouseButtonCallback);
return 0;
}
Notice that you don't call glutMouseFunc directly anymore; it is managed as part of [un]set_mousefunc.
Just in case it isn't clear: I've rewritten this answer so it should work for you and so that it avoids the C/C++ linkage issue being debated. It will compile and run as-is (without glut), and it should work with glut with only minor modification: comment or uncomment the 4 lines marked ##E##.
No, a pointer to an instance function can not be given to a callback function expecting a function pointer of a certain signature. Their signatures are different. It won't compile.
Generally such APIs allow you to pass in a void* as a "context" parameter. You pass in your object there, and write a wrapper function which takes the context as the callback. The wrapper casts it back to whatever class you were using, and calls the appropriate member function.
You can't replace a static callback with an instance one. When the caller calls your callback, on what instance whoul it call? In other words, how does the caller pass in the formal 'this' argument?
The solution is to have a static callback stub and pass the instance as argument, which implies the callee must accept an arbitrary pvoid that will pass back when invoking the callback. In the stub, you can then call the non-static method:
class C {
void f() {...}
static void F(void* p) {
C* pC = (C*)p;
pC->f();
}
}
C* pC = ...;
someComponent.setCallback(&C::F, pC);
Contrary to what everyone seems to be saying, you most definitely CAN use a non-static member function as a callback method. It requires special syntax designed specifically for getting pointers to non-static members, and special syntax to call that function on a specific instance of a class. See here for a discussion of the needed syntax.
Here is sample code that illustrates how this works:
#include <cstdlib>
#include <string>
#include <iostream>
#include <vector>
#include <sstream>
#include <algorithm>
using namespace std;
class Operational
{
public:
Operational(int value) : value_(value) {};
string FormatValue() const ;
private:
int value_;
};
string Operational::FormatValue() const
{
stringstream ss;
ss << "My value is " << value_;
return ss.str();
}
typedef string(Operational::*FormatFn)() const; // note the funky syntax
Operational make_oper(int val)
{
return Operational(val);
}
int main()
{
// build the list of objects with the instance callbacks we want to call
Operational ops[] = {1, 2, 3, 5, 8, 13};
size_t numOps = sizeof(ops)/sizeof(ops[0]);
// now call the instance callbacks
for( size_t i = 0; i < numOps; ++i )
{
// get the function pointer
FormatFn fn = &Operational::FormatValue;
// get a pointer to the instance
Operational* op = &ops[i];
// call the callback on the instance
string retval = (op->*fn)();
// display the output
cout << "The object # " << hex << (void*)op << " said: '" << retval << "'" << endl;
}
return 0;
}
The output of this program when I ran it on my machine was:
The object # 0017F938 said: 'My value is 1'
The object # 0017F93C said: 'My value is 2'
The object # 0017F940 said: 'My value is 3'
The object # 0017F944 said: 'My value is 5'
The object # 0017F948 said: 'My value is 8'
The object # 0017F94C said: 'My value is 13'
You cannot use a non-static member function in this case.
Basically the type of the argument expected by glutMouseFunc is
void (*)(int, int, int, int)
while the type of your non-static member function is
void (StartHand::*)(int, int, int, int)
First problem is that types don't really match.
Second, in order to be able to call that method, the callback would have to know which object ( i.e. "this" pointer ) your method belongs to ( that's pretty much why the types are different in the first place ).
And third, I think you're using the wrong syntax to retrieve the method's pointer. The right syntax should be: &StartHand::MouseButton.
So, you have to either make that method static or use some other static method that would know which StartHand pointer to use to call MouseButton.
The following works in c++ to define a c callback function, useful for example when using glut (glutDisplayFunc, glutKeyboardFunc, glutMouseFunc ...) when you only need a single instance of this class :
MyClass * ptr_global_instance = NULL;
extern "C" void mouse_buttons_callback(int button, int state, int x, int y) {
// c function call which calls your c++ class method
ptr_global_instance->mouse_buttons_cb(button, state, x, y);
}
void MyClass::mouse_buttons_cb(int button, int state, int x, int y) {
// this is actual body of callback - ie. if (button == GLUT_LEFT_BUTTON) ...
// implemented as a c++ method
}
void MyClass::setup_glut(int argc, char** argv) { // largely boilerplate glut setup
glutInit(&argc, argv);
// ... the usual suspects go here like glutInitWindowSize(900, 800); ...
setupMouseButtonCallback(); // <-- custom linkage of c++ to cb
// ... other glut setup calls here
}
void MyClass::setupMouseButtonCallback() {
// c++ method which registers c function callback
::ptr_global_instance = this;
::glutMouseFunc(::mouse_buttons_callback);
}
In your MyClass header we add :
void mouse_buttons_cb(int button, int state, int x, int y);
void setupMouseButtonCallback();
This also works using identical logic flows to setup your glut
call to glutDisplayFunc(display)