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;
}









share|improve this question




























    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;
    }









    share|improve this question


























      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;
      }









      share|improve this question















      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






      share|improve this question















      share|improve this question













      share|improve this question




      share|improve this question








      edited Nov 11 at 23:26

























      asked Nov 11 at 13:19









      IanQ

      33




      33
























          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





          share|improve this answer























          • 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












          • 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











          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          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

























          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





          share|improve this answer























          • 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












          • 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















          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





          share|improve this answer























          • 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












          • 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













          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





          share|improve this answer














          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






          share|improve this answer














          share|improve this answer



          share|improve this answer








          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 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










          • 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












          • 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










          • 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


















          draft saved

          draft discarded




















































          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.




          draft saved


          draft discarded














          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





















































          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







          Popular posts from this blog

          Full-time equivalent

          Bicuculline

          さくらももこ