初始化一个 const char **
Initializing a const char **
编辑:删除了一些无用的代码
我正在为我的游戏的 GUI 库使用 IMGUI,并且我正在尝试实现列表框。但是我的 const char ** 似乎没有被 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();
}
}
将此文件与我的项目的其余部分一起编译我得到一个 window 看起来像这样的
https://s4.postimg.org/cyrdl2p8d/DMUX_130.png
如您所见,它没有打印出 const char ** 的全部内容。但是 cout 语句正确地打印出数组的内容应该是
- "El Camino"
- "Moscovitch"
- "ElCamino"
没有引号,它会正确获取第一个值,如图所示。我在涉及 names 变量的初始化方面有什么问题吗?
sizeof 很奇怪,因为 IMGUI imgui_demo.cpp 中的代码将此宏用于列表框
上的 sizeof
#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
所以我只是采用原始输入而不是使用定义。
它按照您的指示进行操作:在列表框中显示 1 个选项。您对列表元素数量的计算是错误的。 sizeof(names)
与 sizeof(*names)
相同,因为两者都是指针。
编辑:输入更好的答案
看了一整天我明白了!我通过说
来修复它
availableChassis.size()
我设法修复了它,谢谢@Ismail Badawi @Paul 和@1201ProgramAlarm 为我指明了正确的方向。
此外,如果您的数据不是那种 const char* [] 格式,那么您可以将 lambda 传递给 ListBox 以直接从您的 availableChassis[] 名称访问您的字符串,而不是创建一个临时数组。
编辑:删除了一些无用的代码
我正在为我的游戏的 GUI 库使用 IMGUI,并且我正在尝试实现列表框。但是我的 const char ** 似乎没有被 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();
}
}
将此文件与我的项目的其余部分一起编译我得到一个 window 看起来像这样的
https://s4.postimg.org/cyrdl2p8d/DMUX_130.png
如您所见,它没有打印出 const char ** 的全部内容。但是 cout 语句正确地打印出数组的内容应该是
- "El Camino"
- "Moscovitch"
- "ElCamino"
没有引号,它会正确获取第一个值,如图所示。我在涉及 names 变量的初始化方面有什么问题吗? sizeof 很奇怪,因为 IMGUI imgui_demo.cpp 中的代码将此宏用于列表框
上的 sizeof#define IM_ARRAYSIZE(_ARR) ((int)(sizeof(_ARR)/sizeof(*_ARR)))
所以我只是采用原始输入而不是使用定义。
它按照您的指示进行操作:在列表框中显示 1 个选项。您对列表元素数量的计算是错误的。 sizeof(names)
与 sizeof(*names)
相同,因为两者都是指针。
编辑:输入更好的答案
看了一整天我明白了!我通过说
来修复它availableChassis.size()
我设法修复了它,谢谢@Ismail Badawi @Paul 和@1201ProgramAlarm 为我指明了正确的方向。
此外,如果您的数据不是那种 const char* [] 格式,那么您可以将 lambda 传递给 ListBox 以直接从您的 availableChassis[] 名称访问您的字符串,而不是创建一个临时数组。