Cast pointer to vector type in callback
up vote
0
down vote
favorite
Weekend programmer, newbie to C++, battling the war of the pointers!
I am trying to code in C++ a method to retrieve data from an API using a vector that gets passed via a void * argument to a callback function.
The returned data will get passed back to lua, which is the front-end used in the application. The lua portion is not what has me baffled, it is the challenge of getting my struct filled with the data from the callback.
I had this all working using simple int pointers, but was told of a preferred way to do it using a struct, it was suggested I do the following:
1 - define a struct that contains the 6 ints
2 - create an std::vector that can contain instances of the new struct
3 - pass a pointer to the vector as refcon into XPLMGetAllMonitorBoundsGlobal
inside the callback function:
4 - cast the refcon pointer back to the vector type
5 - create a new instance of the struct and fill it with the 6 ints that are passed to the callback function
6 - push that instance into the vector
7 - when XPLMGetAllMonitorBoundsGlobal returns, the vector will be filled with the bounds of all screens
8 - convert the vector into a lua-compatible thing, probably a two-dimensional array
push that array into lua
Here is the code I came up with, did lot's of Google/Stackoverflow searches to come this close, but even though the code compiles, it hangs the application, or causes seg faults, depends on what I tweaked. I think the primary problem is how I am casting the refcon pointer back to a vector type, too many references/dereferences of pointers, and there are probably other issues too.
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
int RefCon;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
vector<MonitorBoundsStructure*>& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon); #4
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure>* MonitorBounds = static_cast<vector<MonitorBoundsStructure> *>(refcon);
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
returnData.RefCon = *(int *)refcon;
MonitorBounds.push_back(&returnData); // #6
}
static int LuaXPLMGetAllMonitorBoundsOSTest()
{
//std::vector<std::shared_ptr<MonitorBoundsStructure>> MonitorBounds;
vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
int i = 0;
for (vector<MonitorBoundsStructure>::iterator it = MonitorBounds.begin(); it != MonitorBounds.end(); ++it)
{
i++;
logMsg(logToAll, string("MonitorBounds ").append(to_string(i)));
}
return 1;
}
If I comment out MonitorBounds.push_back(&returnData), The code will at least get to where the struct inside the callback is filled with the correct data, I am hitting a wall getting that struct back to the calling function, meaning my cast of the void* to vector is wrong at the very least.
I left some of my other attempts in the comments to show what I have tried.
Am I close to the solution or way off?
Solution:
Thanks to Ted Lyngmo for providing the solution, even going as far as to write up test code on his own system. My problem, as I suspected, was in the cast of pointer to vector. I have included both the push_back and emplace_back (much neater I find) answers.
-callback function:
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBoundsStructure returnData;
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
MonitorBounds.push_back(returnData);
}
and
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
-calling function:
static int LuaXPLMGetAllMonitorBoundsOSTestE(lua_State *L)
{
vector<MonitorBoundsStructure> MonitorBounds;
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_e, &MonitorBounds);
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
c++ lua
add a comment |
up vote
0
down vote
favorite
Weekend programmer, newbie to C++, battling the war of the pointers!
I am trying to code in C++ a method to retrieve data from an API using a vector that gets passed via a void * argument to a callback function.
The returned data will get passed back to lua, which is the front-end used in the application. The lua portion is not what has me baffled, it is the challenge of getting my struct filled with the data from the callback.
I had this all working using simple int pointers, but was told of a preferred way to do it using a struct, it was suggested I do the following:
1 - define a struct that contains the 6 ints
2 - create an std::vector that can contain instances of the new struct
3 - pass a pointer to the vector as refcon into XPLMGetAllMonitorBoundsGlobal
inside the callback function:
4 - cast the refcon pointer back to the vector type
5 - create a new instance of the struct and fill it with the 6 ints that are passed to the callback function
6 - push that instance into the vector
7 - when XPLMGetAllMonitorBoundsGlobal returns, the vector will be filled with the bounds of all screens
8 - convert the vector into a lua-compatible thing, probably a two-dimensional array
push that array into lua
Here is the code I came up with, did lot's of Google/Stackoverflow searches to come this close, but even though the code compiles, it hangs the application, or causes seg faults, depends on what I tweaked. I think the primary problem is how I am casting the refcon pointer back to a vector type, too many references/dereferences of pointers, and there are probably other issues too.
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
int RefCon;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
vector<MonitorBoundsStructure*>& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon); #4
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure>* MonitorBounds = static_cast<vector<MonitorBoundsStructure> *>(refcon);
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
returnData.RefCon = *(int *)refcon;
MonitorBounds.push_back(&returnData); // #6
}
static int LuaXPLMGetAllMonitorBoundsOSTest()
{
//std::vector<std::shared_ptr<MonitorBoundsStructure>> MonitorBounds;
vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
int i = 0;
for (vector<MonitorBoundsStructure>::iterator it = MonitorBounds.begin(); it != MonitorBounds.end(); ++it)
{
i++;
logMsg(logToAll, string("MonitorBounds ").append(to_string(i)));
}
return 1;
}
If I comment out MonitorBounds.push_back(&returnData), The code will at least get to where the struct inside the callback is filled with the correct data, I am hitting a wall getting that struct back to the calling function, meaning my cast of the void* to vector is wrong at the very least.
I left some of my other attempts in the comments to show what I have tried.
Am I close to the solution or way off?
Solution:
Thanks to Ted Lyngmo for providing the solution, even going as far as to write up test code on his own system. My problem, as I suspected, was in the cast of pointer to vector. I have included both the push_back and emplace_back (much neater I find) answers.
-callback function:
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBoundsStructure returnData;
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
MonitorBounds.push_back(returnData);
}
and
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
-calling function:
static int LuaXPLMGetAllMonitorBoundsOSTestE(lua_State *L)
{
vector<MonitorBoundsStructure> MonitorBounds;
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_e, &MonitorBounds);
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
c++ lua
add a comment |
up vote
0
down vote
favorite
up vote
0
down vote
favorite
Weekend programmer, newbie to C++, battling the war of the pointers!
I am trying to code in C++ a method to retrieve data from an API using a vector that gets passed via a void * argument to a callback function.
The returned data will get passed back to lua, which is the front-end used in the application. The lua portion is not what has me baffled, it is the challenge of getting my struct filled with the data from the callback.
I had this all working using simple int pointers, but was told of a preferred way to do it using a struct, it was suggested I do the following:
1 - define a struct that contains the 6 ints
2 - create an std::vector that can contain instances of the new struct
3 - pass a pointer to the vector as refcon into XPLMGetAllMonitorBoundsGlobal
inside the callback function:
4 - cast the refcon pointer back to the vector type
5 - create a new instance of the struct and fill it with the 6 ints that are passed to the callback function
6 - push that instance into the vector
7 - when XPLMGetAllMonitorBoundsGlobal returns, the vector will be filled with the bounds of all screens
8 - convert the vector into a lua-compatible thing, probably a two-dimensional array
push that array into lua
Here is the code I came up with, did lot's of Google/Stackoverflow searches to come this close, but even though the code compiles, it hangs the application, or causes seg faults, depends on what I tweaked. I think the primary problem is how I am casting the refcon pointer back to a vector type, too many references/dereferences of pointers, and there are probably other issues too.
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
int RefCon;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
vector<MonitorBoundsStructure*>& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon); #4
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure>* MonitorBounds = static_cast<vector<MonitorBoundsStructure> *>(refcon);
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
returnData.RefCon = *(int *)refcon;
MonitorBounds.push_back(&returnData); // #6
}
static int LuaXPLMGetAllMonitorBoundsOSTest()
{
//std::vector<std::shared_ptr<MonitorBoundsStructure>> MonitorBounds;
vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
int i = 0;
for (vector<MonitorBoundsStructure>::iterator it = MonitorBounds.begin(); it != MonitorBounds.end(); ++it)
{
i++;
logMsg(logToAll, string("MonitorBounds ").append(to_string(i)));
}
return 1;
}
If I comment out MonitorBounds.push_back(&returnData), The code will at least get to where the struct inside the callback is filled with the correct data, I am hitting a wall getting that struct back to the calling function, meaning my cast of the void* to vector is wrong at the very least.
I left some of my other attempts in the comments to show what I have tried.
Am I close to the solution or way off?
Solution:
Thanks to Ted Lyngmo for providing the solution, even going as far as to write up test code on his own system. My problem, as I suspected, was in the cast of pointer to vector. I have included both the push_back and emplace_back (much neater I find) answers.
-callback function:
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBoundsStructure returnData;
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
MonitorBounds.push_back(returnData);
}
and
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
-calling function:
static int LuaXPLMGetAllMonitorBoundsOSTestE(lua_State *L)
{
vector<MonitorBoundsStructure> MonitorBounds;
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_e, &MonitorBounds);
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
c++ lua
Weekend programmer, newbie to C++, battling the war of the pointers!
I am trying to code in C++ a method to retrieve data from an API using a vector that gets passed via a void * argument to a callback function.
The returned data will get passed back to lua, which is the front-end used in the application. The lua portion is not what has me baffled, it is the challenge of getting my struct filled with the data from the callback.
I had this all working using simple int pointers, but was told of a preferred way to do it using a struct, it was suggested I do the following:
1 - define a struct that contains the 6 ints
2 - create an std::vector that can contain instances of the new struct
3 - pass a pointer to the vector as refcon into XPLMGetAllMonitorBoundsGlobal
inside the callback function:
4 - cast the refcon pointer back to the vector type
5 - create a new instance of the struct and fill it with the 6 ints that are passed to the callback function
6 - push that instance into the vector
7 - when XPLMGetAllMonitorBoundsGlobal returns, the vector will be filled with the bounds of all screens
8 - convert the vector into a lua-compatible thing, probably a two-dimensional array
push that array into lua
Here is the code I came up with, did lot's of Google/Stackoverflow searches to come this close, but even though the code compiles, it hangs the application, or causes seg faults, depends on what I tweaked. I think the primary problem is how I am casting the refcon pointer back to a vector type, too many references/dereferences of pointers, and there are probably other issues too.
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
int RefCon;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
vector<MonitorBoundsStructure*>& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon); #4
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure*> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure> MonitorBounds = reinterpret_cast<vector<MonitorBoundsStructure> *>(refcon);
//vector<MonitorBoundsStructure>* MonitorBounds = static_cast<vector<MonitorBoundsStructure> *>(refcon);
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
returnData.RefCon = *(int *)refcon;
MonitorBounds.push_back(&returnData); // #6
}
static int LuaXPLMGetAllMonitorBoundsOSTest()
{
//std::vector<std::shared_ptr<MonitorBoundsStructure>> MonitorBounds;
vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
int i = 0;
for (vector<MonitorBoundsStructure>::iterator it = MonitorBounds.begin(); it != MonitorBounds.end(); ++it)
{
i++;
logMsg(logToAll, string("MonitorBounds ").append(to_string(i)));
}
return 1;
}
If I comment out MonitorBounds.push_back(&returnData), The code will at least get to where the struct inside the callback is filled with the correct data, I am hitting a wall getting that struct back to the calling function, meaning my cast of the void* to vector is wrong at the very least.
I left some of my other attempts in the comments to show what I have tried.
Am I close to the solution or way off?
Solution:
Thanks to Ted Lyngmo for providing the solution, even going as far as to write up test code on his own system. My problem, as I suspected, was in the cast of pointer to vector. I have included both the push_back and emplace_back (much neater I find) answers.
-callback function:
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBoundsStructure returnData;
returnData.MonitorIndex = inMonitorIndex;
returnData.LeftBx = inLeftBx;
returnData.TopBx = inTopBx;
returnData.RightBx = inRightBx;
returnData.BottomBx = inBottomBx;
MonitorBounds.push_back(returnData);
}
and
static void LuaReceiveMonitorBoundsOS_e(int inMonitorIndex, int inLeftBx, int inTopBx, int inRightBx, int inBottomBx, void * refcon)
{
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
-calling function:
static int LuaXPLMGetAllMonitorBoundsOSTestE(lua_State *L)
{
vector<MonitorBoundsStructure> MonitorBounds;
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_e, &MonitorBounds);
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
c++ lua
c++ lua
edited Nov 11 at 23:26
asked Nov 11 at 13:19
IanQ
33
33
add a comment |
add a comment |
1 Answer
1
active
oldest
votes
up vote
2
down vote
accepted
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
MonitorBounds.push_back(&returnData); // #6
After that, returnData gets out of scope and is destroyed. The pointer you now have in MonitorBounds is invalid.
It also looks like you are casting to the wrong type. If this is the vector:
vector<MonitorBoundsStructure> MonitorBounds;
You should cast to that in your calllback:
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
And push the whole struct and not a pointer to it:
MonitorBounds.push_back(returnData);
Edit: I made a test version with my own XPLMGetAllMonitorBoundsOS
to check that it's working and it looks ok.
#include <iostream>
#include <string>
#include <vector>
typedef void (*XPLMReceiveMonitorBoundsOS_f)( int inMonitorIndex,
int inLeftPx,
int inTopPx,
int inRightPx,
int inBottomPx,
void* inRefcon);
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx,
int inRightBx, int inBottomBx, void* refcon)
{
auto& MonitorBounds = *reinterpret_cast<std::vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
void XPLMGetAllMonitorBoundsOS(XPLMReceiveMonitorBoundsOS_f callback, void* inRefcon)
{
callback(0,100,0,100,100, inRefcon);
callback(1,99,1,99,99, inRefcon);
callback(2,100,1,100,100, inRefcon);
}
static int LuaXPLMGetAllMonitorBoundsOSTest() {
std::vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
int main() {
LuaXPLMGetAllMonitorBoundsOSTest();
}
Output
0
1
2
Thanks for the quick response. I made the changes to my cast and push_back as you suggested, but getting seg faults. Again, it seems the push_back is in question...
– IanQ
Nov 11 at 15:32
Do you have a debugger so you can see exactly where it seg faults? I would remove the RefCon member from the struct and alsoreturnData.RefCon = *(int *)refcon
. If an int is larger than an address, that casues undefined behaviour.
– Ted Lyngmo
Nov 11 at 16:03
Added a little test version
– Ted Lyngmo
Nov 11 at 16:49
I got it to work, both your first suggestion, and the follow-up using .emplace_back instead of push_back (which I much prefer). The problem I had with your first suggestion was due to some residual code I had kept in the callback function that was working with a simple int pointer, apparently it interferes with the new code. My bad for keeping it in there, I thought it harmless when it wasn't. Thanks very much for your help!
– IanQ
Nov 11 at 23:05
And forgot to mention that this works even with the RefCon member, though I think in the end I will remove it as I don't need it.
– IanQ
Nov 11 at 23:27
|
show 1 more comment
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
2
down vote
accepted
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
MonitorBounds.push_back(&returnData); // #6
After that, returnData gets out of scope and is destroyed. The pointer you now have in MonitorBounds is invalid.
It also looks like you are casting to the wrong type. If this is the vector:
vector<MonitorBoundsStructure> MonitorBounds;
You should cast to that in your calllback:
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
And push the whole struct and not a pointer to it:
MonitorBounds.push_back(returnData);
Edit: I made a test version with my own XPLMGetAllMonitorBoundsOS
to check that it's working and it looks ok.
#include <iostream>
#include <string>
#include <vector>
typedef void (*XPLMReceiveMonitorBoundsOS_f)( int inMonitorIndex,
int inLeftPx,
int inTopPx,
int inRightPx,
int inBottomPx,
void* inRefcon);
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx,
int inRightBx, int inBottomBx, void* refcon)
{
auto& MonitorBounds = *reinterpret_cast<std::vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
void XPLMGetAllMonitorBoundsOS(XPLMReceiveMonitorBoundsOS_f callback, void* inRefcon)
{
callback(0,100,0,100,100, inRefcon);
callback(1,99,1,99,99, inRefcon);
callback(2,100,1,100,100, inRefcon);
}
static int LuaXPLMGetAllMonitorBoundsOSTest() {
std::vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
int main() {
LuaXPLMGetAllMonitorBoundsOSTest();
}
Output
0
1
2
Thanks for the quick response. I made the changes to my cast and push_back as you suggested, but getting seg faults. Again, it seems the push_back is in question...
– IanQ
Nov 11 at 15:32
Do you have a debugger so you can see exactly where it seg faults? I would remove the RefCon member from the struct and alsoreturnData.RefCon = *(int *)refcon
. If an int is larger than an address, that casues undefined behaviour.
– Ted Lyngmo
Nov 11 at 16:03
Added a little test version
– Ted Lyngmo
Nov 11 at 16:49
I got it to work, both your first suggestion, and the follow-up using .emplace_back instead of push_back (which I much prefer). The problem I had with your first suggestion was due to some residual code I had kept in the callback function that was working with a simple int pointer, apparently it interferes with the new code. My bad for keeping it in there, I thought it harmless when it wasn't. Thanks very much for your help!
– IanQ
Nov 11 at 23:05
And forgot to mention that this works even with the RefCon member, though I think in the end I will remove it as I don't need it.
– IanQ
Nov 11 at 23:27
|
show 1 more comment
up vote
2
down vote
accepted
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
MonitorBounds.push_back(&returnData); // #6
After that, returnData gets out of scope and is destroyed. The pointer you now have in MonitorBounds is invalid.
It also looks like you are casting to the wrong type. If this is the vector:
vector<MonitorBoundsStructure> MonitorBounds;
You should cast to that in your calllback:
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
And push the whole struct and not a pointer to it:
MonitorBounds.push_back(returnData);
Edit: I made a test version with my own XPLMGetAllMonitorBoundsOS
to check that it's working and it looks ok.
#include <iostream>
#include <string>
#include <vector>
typedef void (*XPLMReceiveMonitorBoundsOS_f)( int inMonitorIndex,
int inLeftPx,
int inTopPx,
int inRightPx,
int inBottomPx,
void* inRefcon);
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx,
int inRightBx, int inBottomBx, void* refcon)
{
auto& MonitorBounds = *reinterpret_cast<std::vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
void XPLMGetAllMonitorBoundsOS(XPLMReceiveMonitorBoundsOS_f callback, void* inRefcon)
{
callback(0,100,0,100,100, inRefcon);
callback(1,99,1,99,99, inRefcon);
callback(2,100,1,100,100, inRefcon);
}
static int LuaXPLMGetAllMonitorBoundsOSTest() {
std::vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
int main() {
LuaXPLMGetAllMonitorBoundsOSTest();
}
Output
0
1
2
Thanks for the quick response. I made the changes to my cast and push_back as you suggested, but getting seg faults. Again, it seems the push_back is in question...
– IanQ
Nov 11 at 15:32
Do you have a debugger so you can see exactly where it seg faults? I would remove the RefCon member from the struct and alsoreturnData.RefCon = *(int *)refcon
. If an int is larger than an address, that casues undefined behaviour.
– Ted Lyngmo
Nov 11 at 16:03
Added a little test version
– Ted Lyngmo
Nov 11 at 16:49
I got it to work, both your first suggestion, and the follow-up using .emplace_back instead of push_back (which I much prefer). The problem I had with your first suggestion was due to some residual code I had kept in the callback function that was working with a simple int pointer, apparently it interferes with the new code. My bad for keeping it in there, I thought it harmless when it wasn't. Thanks very much for your help!
– IanQ
Nov 11 at 23:05
And forgot to mention that this works even with the RefCon member, though I think in the end I will remove it as I don't need it.
– IanQ
Nov 11 at 23:27
|
show 1 more comment
up vote
2
down vote
accepted
up vote
2
down vote
accepted
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
MonitorBounds.push_back(&returnData); // #6
After that, returnData gets out of scope and is destroyed. The pointer you now have in MonitorBounds is invalid.
It also looks like you are casting to the wrong type. If this is the vector:
vector<MonitorBoundsStructure> MonitorBounds;
You should cast to that in your calllback:
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
And push the whole struct and not a pointer to it:
MonitorBounds.push_back(returnData);
Edit: I made a test version with my own XPLMGetAllMonitorBoundsOS
to check that it's working and it looks ok.
#include <iostream>
#include <string>
#include <vector>
typedef void (*XPLMReceiveMonitorBoundsOS_f)( int inMonitorIndex,
int inLeftPx,
int inTopPx,
int inRightPx,
int inBottomPx,
void* inRefcon);
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx,
int inRightBx, int inBottomBx, void* refcon)
{
auto& MonitorBounds = *reinterpret_cast<std::vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
void XPLMGetAllMonitorBoundsOS(XPLMReceiveMonitorBoundsOS_f callback, void* inRefcon)
{
callback(0,100,0,100,100, inRefcon);
callback(1,99,1,99,99, inRefcon);
callback(2,100,1,100,100, inRefcon);
}
static int LuaXPLMGetAllMonitorBoundsOSTest() {
std::vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
int main() {
LuaXPLMGetAllMonitorBoundsOSTest();
}
Output
0
1
2
MonitorBoundsStructure returnData; //{0,0,0,0,0,0}; #5
MonitorBounds.push_back(&returnData); // #6
After that, returnData gets out of scope and is destroyed. The pointer you now have in MonitorBounds is invalid.
It also looks like you are casting to the wrong type. If this is the vector:
vector<MonitorBoundsStructure> MonitorBounds;
You should cast to that in your calllback:
auto& MonitorBounds = *reinterpret_cast<vector<MonitorBoundsStructure>*>(refcon);
And push the whole struct and not a pointer to it:
MonitorBounds.push_back(returnData);
Edit: I made a test version with my own XPLMGetAllMonitorBoundsOS
to check that it's working and it looks ok.
#include <iostream>
#include <string>
#include <vector>
typedef void (*XPLMReceiveMonitorBoundsOS_f)( int inMonitorIndex,
int inLeftPx,
int inTopPx,
int inRightPx,
int inBottomPx,
void* inRefcon);
struct MonitorBoundsStructure // #1
{
int MonitorIndex;
int LeftBx;
int TopBx;
int RightBx;
int BottomBx;
};
static void LuaReceiveMonitorBoundsOS_t(int inMonitorIndex, int inLeftBx, int inTopBx,
int inRightBx, int inBottomBx, void* refcon)
{
auto& MonitorBounds = *reinterpret_cast<std::vector<MonitorBoundsStructure>*>(refcon);
MonitorBounds.emplace_back(
MonitorBoundsStructure{
inMonitorIndex,
inLeftBx,
inTopBx,
inRightBx,
inBottomBx
}
);
}
void XPLMGetAllMonitorBoundsOS(XPLMReceiveMonitorBoundsOS_f callback, void* inRefcon)
{
callback(0,100,0,100,100, inRefcon);
callback(1,99,1,99,99, inRefcon);
callback(2,100,1,100,100, inRefcon);
}
static int LuaXPLMGetAllMonitorBoundsOSTest() {
std::vector<MonitorBoundsStructure> MonitorBounds; // #2
XPLMGetAllMonitorBoundsOS(LuaReceiveMonitorBoundsOS_t, &MonitorBounds); // #3
for (auto& m : MonitorBounds) {
std::cout << m.MonitorIndex << "n";
}
return 1;
}
int main() {
LuaXPLMGetAllMonitorBoundsOSTest();
}
Output
0
1
2
edited Nov 11 at 16:47
answered Nov 11 at 13:27
Ted Lyngmo
1,343214
1,343214
Thanks for the quick response. I made the changes to my cast and push_back as you suggested, but getting seg faults. Again, it seems the push_back is in question...
– IanQ
Nov 11 at 15:32
Do you have a debugger so you can see exactly where it seg faults? I would remove the RefCon member from the struct and alsoreturnData.RefCon = *(int *)refcon
. If an int is larger than an address, that casues undefined behaviour.
– Ted Lyngmo
Nov 11 at 16:03
Added a little test version
– Ted Lyngmo
Nov 11 at 16:49
I got it to work, both your first suggestion, and the follow-up using .emplace_back instead of push_back (which I much prefer). The problem I had with your first suggestion was due to some residual code I had kept in the callback function that was working with a simple int pointer, apparently it interferes with the new code. My bad for keeping it in there, I thought it harmless when it wasn't. Thanks very much for your help!
– IanQ
Nov 11 at 23:05
And forgot to mention that this works even with the RefCon member, though I think in the end I will remove it as I don't need it.
– IanQ
Nov 11 at 23:27
|
show 1 more comment
Thanks for the quick response. I made the changes to my cast and push_back as you suggested, but getting seg faults. Again, it seems the push_back is in question...
– IanQ
Nov 11 at 15:32
Do you have a debugger so you can see exactly where it seg faults? I would remove the RefCon member from the struct and alsoreturnData.RefCon = *(int *)refcon
. If an int is larger than an address, that casues undefined behaviour.
– Ted Lyngmo
Nov 11 at 16:03
Added a little test version
– Ted Lyngmo
Nov 11 at 16:49
I got it to work, both your first suggestion, and the follow-up using .emplace_back instead of push_back (which I much prefer). The problem I had with your first suggestion was due to some residual code I had kept in the callback function that was working with a simple int pointer, apparently it interferes with the new code. My bad for keeping it in there, I thought it harmless when it wasn't. Thanks very much for your help!
– IanQ
Nov 11 at 23:05
And forgot to mention that this works even with the RefCon member, though I think in the end I will remove it as I don't need it.
– IanQ
Nov 11 at 23:27
Thanks for the quick response. I made the changes to my cast and push_back as you suggested, but getting seg faults. Again, it seems the push_back is in question...
– IanQ
Nov 11 at 15:32
Thanks for the quick response. I made the changes to my cast and push_back as you suggested, but getting seg faults. Again, it seems the push_back is in question...
– IanQ
Nov 11 at 15:32
Do you have a debugger so you can see exactly where it seg faults? I would remove the RefCon member from the struct and also
returnData.RefCon = *(int *)refcon
. If an int is larger than an address, that casues undefined behaviour.– Ted Lyngmo
Nov 11 at 16:03
Do you have a debugger so you can see exactly where it seg faults? I would remove the RefCon member from the struct and also
returnData.RefCon = *(int *)refcon
. If an int is larger than an address, that casues undefined behaviour.– Ted Lyngmo
Nov 11 at 16:03
Added a little test version
– Ted Lyngmo
Nov 11 at 16:49
Added a little test version
– Ted Lyngmo
Nov 11 at 16:49
I got it to work, both your first suggestion, and the follow-up using .emplace_back instead of push_back (which I much prefer). The problem I had with your first suggestion was due to some residual code I had kept in the callback function that was working with a simple int pointer, apparently it interferes with the new code. My bad for keeping it in there, I thought it harmless when it wasn't. Thanks very much for your help!
– IanQ
Nov 11 at 23:05
I got it to work, both your first suggestion, and the follow-up using .emplace_back instead of push_back (which I much prefer). The problem I had with your first suggestion was due to some residual code I had kept in the callback function that was working with a simple int pointer, apparently it interferes with the new code. My bad for keeping it in there, I thought it harmless when it wasn't. Thanks very much for your help!
– IanQ
Nov 11 at 23:05
And forgot to mention that this works even with the RefCon member, though I think in the end I will remove it as I don't need it.
– IanQ
Nov 11 at 23:27
And forgot to mention that this works even with the RefCon member, though I think in the end I will remove it as I don't need it.
– IanQ
Nov 11 at 23:27
|
show 1 more comment
Thanks for contributing an answer to Stack Overflow!
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Some of your past answers have not been well-received, and you're in danger of being blocked from answering.
Please pay close attention to the following guidance:
- Please be sure to answer the question. Provide details and share your research!
But avoid …
- Asking for help, clarification, or responding to other answers.
- Making statements based on opinion; back them up with references or personal experience.
To learn more, see our tips on writing great answers.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
StackExchange.ready(
function () {
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53249141%2fcast-pointer-to-vector-type-in-callback%23new-answer', 'question_page');
}
);
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown
Required, but never shown