简体   繁体   中英

Initializing a const char **

Edit: Removed some unhelpful code

I am using IMGUI for my game's GUI library, and I am trying to implement listboxes. However my const char ** does not seem be read correctly by IMGUI.

#include <tinydir.h>
#include <tinyxml2.h>
#include <cpplocate/ModuleInfo.h>
#include <cpplocate/cpplocate.h>
#include <iostream>
#include <easylogging++.h>

#include "DmuxCommon.hpp"
#include "Garage.hpp"
#include "client/Game.hpp"

irr::f32 garageRotationRate = irr::f32(1.0f);
irr::f32 gChassisRotation;
irr::f32 gCameraRotation;
int selection = 0;

namespace menu {

const char **Garage::names;


  Garage::Garage() :
    Gui(),
    pMainScreen(Game::device->getSceneManager()->addEmptySceneNode()),
    pMoonScreen(Game::device->getSceneManager()->addEmptySceneNode()),
    availableChassis(getAvailableChassises()) {

    // Prepare double rendering
    pRenderTarget = Game::device->getVideoDriver()->addRenderTargetTexture(irr::core::dimension2d<irr::u32>(384, 300), "Moon");

    pRenderTextureID = pGUI->createTexture(pRenderTarget);

    names = new const char *[availableChassis.size()];
    for(unsigned int i = 0; i < availableChassis.size(); ++i) {
      names[i] = availableChassis[i].c_str();
    }

    for(unsigned int i = 0; i < availableChassis.size(); ++i) {
      std::cout << names[i] << std::endl; // This shows the content of the const char ** correctly
    }
  }

  void Garage::show() {

    //Rendering the node
    Game::device->getVideoDriver()->setRenderTarget(pRenderTarget, true, true, irr::video::SColor(255, 120.0f, 120.0f, 120.0f));
    pMoonScreen->setVisible(true);
    pMainScreen->setVisible(false);
    Game::device->getSceneManager()->setActiveCamera(pMoonCam);
    Game::device->getSceneManager()->drawAll();
    Game::device->getVideoDriver()->setRenderTarget(0, true, true, irr::video::SColor(255, 100, 101, 140));

    pMoonScreen->setVisible(false);
    pMainScreen->setVisible(true);
    Game::device->getSceneManager()->setActiveCamera(pMainCam);

    pGUI->updateTexture(pRenderTextureID, pRenderTarget);

    if(gChassis == nullptr) {
      gChassis = Game::device->getSceneManager()->addMeshSceneNode(Game::device->getSceneManager()->getMesh((std::string(cpplocate::findModule("dmux").value("chassisDir") + "el-camino/el-camino.obj")).c_str()));
      gChassis->setParent(pMoonScreen);
      gChassis->setPosition(irr::core::vector3df(0, 0, 0));
      gChassis->setMaterialFlag(irr::video::EMF_LIGHTING, false);
      gChassis->setMaterialFlag(irr::video::EMF_BACK_FACE_CULLING, false);

      pMainCam = Game::device->getSceneManager()->addCameraSceneNode(pMoonScreen, irr::core::vector3df(0, 0, 0), irr::core::vector3df(0, 0, 0));
      pMoonCam = Game::device->getSceneManager()->addCameraSceneNode(pMoonScreen, irr::core::vector3df(0, 0, -5), irr::core::vector3df(0, 0, 0));
      pMoonCam->setTarget(gChassis->getPosition());
      gCameraRotation = irr::f32(1.0f);
    }

    ImGui::SetNextWindowPos(ImVec2(0.0f, 0.0f));
    ImGui::SetNextWindowSize(ImVec2(Game::playerSettings.currentWindowSize.first,
                                    Game::playerSettings.currentWindowSize.second - (Game::playerSettings.currentWindowSize.second / 9)));

    ImGui::Begin("Customize a combat vehicle");

    ImGui::PushItemWidth(120);
    ImGui::ListBox("", &selection, names, ((int)(sizeof(names)/sizeof(*names))));
    ImGui::PopItemWidth();

    ImGui::End();
  }
}

Compiling this file with the rest of my project I get a window that looks like this

https://s4.postimg.org/cyrdl2p8d/DMUX_130.png

As you can see it does not print out the entire contents of the const char ** as it should. But the cout statements are correctly printing out the contents of the array which should be

  • "El Camino"
  • "Moscovitch"
  • "ElCamino"

Without quotes, it is getting the first value correctly as pictured. Is there anything wrong I am doing involving the initialization of the names variable? The sizeof is strange because of the code in IMGUI's imgui_demo.cpp it used this macro for sizeof on listboxes

#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))

So I just took the raw input rather than using the define.

It's doing what you're telling it: Displaying 1 choice in the list box. Your calculation of the number of list elements is wrong. sizeof(names) is the same as sizeof(*names) , since both are pointers.

Edit: putting in better answer

I got it after all day of looking at it! I fixed it by saying

availableChassis.size()

I managed to fix it, thank you @Ismail Badawi @Paul and @1201ProgramAlarm for pointing me in the right direction.

同样,如果您的数据不是const char * []格式,则可以创建一个lambda到ListBox来直接从availableChassis []名称访问字符串,而不是创建一个临时数组。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM