- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我有一个包含这个表的 lua 脚本:
test = {}
test[1] = "Naya"
test[2] = 1000
test[3] = 1
test[4] = 20
我的 C++ 程序中有一个结构体。旨在填充该表中包含的信息:
//Enemy Struct
struct Enemy
{
string name;
int health;
int family;
int level;
} enemy;
为已知大小和已知键名的表填充结构非常容易。
当出现以下情况时,它会变得更具挑战性:
我想要的是使用一个简单的 for 循环来填充这个结构,如下所示:
for (int i = 1; i < length; i++)
{
lua_pushnumber(L, i);
lua_gettable(L, -2);
if (lua_isnumber(L, -1))
enemy.at(i)? = lua_tonumber(L, -1);
else
enemy.at(i) ? = lua_tostring(L, -1);
lua_pop(L, 1);
}
Struct 没有.at(x)
函数。因此我不能使用这个简单的循环遍历结构来填充它。
我考虑过使用带有 vector/结构的二维数组。但我不确定这是否有效。
我希望 Struct 使用循环填充来自 lua 脚本的数据。
最佳答案
您需要某种反射才能动态获取索引 i 处的成员。
不幸的是,标准 C++ 中没有任何东西可以为您做到这一点。
有几种方法可以让它发挥作用:
Enemy e;
lua_pushnumber(L, 1);
lua_gettable(L, -2);
e.name = lua_tostring(L, -1);
// ...
但是,如果您有很多成员,这将很快变得非常困惑。
Enemy
结构,例如:std::vector<std::string> enemy;
for(int i = 0; i < length; i++) {
lua_pushnumber(L, i);
lua_gettable(L, -2);
enemy.push_back(lua_tostring(state, -1));
lua_pop(L, 1);
}
此解决方案的明显缺点是您需要在 vector 中使用索引,而不是像 health
、name
等花哨的名称。到单一类型。
boost
你可以使用 BOOST_FUSION_ADAPT_STRUCT
来自 boost::fusion
以及 boost::fusion::for_each
以及动态分配成员变量的访问者,例如:#include <boost/fusion/adapted/struct/adapt_struct.hpp>
#include <boost/fusion/include/adapt_struct.hpp>
#include <boost/fusion/algorithm/iteration.hpp>
#include <lua/lua.hpp>
struct Enemy
{
std::string name;
int health;
int family;
int level;
} enemy;
BOOST_FUSION_ADAPT_STRUCT(
Enemy,
(std::string, name)
(int, health)
(int, family)
(int, level)
)
struct LuaVisitor {
LuaVisitor(lua_State* state) : idx(1), state(state) {}
void operator()(std::string& strVal) const {
next();
// TODO: check if top of stack is actually a string (might be nil if key doesn't exist in table)
strVal = lua_tostring(state, -1);
lua_pop(state, 1);
}
void operator()(int& intVal) const {
next();
// TODO: check if top of stack is actually a number (might be nil if key doesn't exist in table)
intVal = lua_tonumber(state, -1);
lua_pop(state, 1);
}
void next() const {
lua_pushnumber(state, idx++);
lua_gettable(state, -2);
}
mutable int idx;
lua_State* state;
};
int main(int argc, char* argv[]) {
// create a sample table
lua_State* state = luaL_newstate();
luaL_dostring(state, "return {\"Hello World\", 1337, 12, 123}");
// read the enemy from the table
Enemy e;
boost::fusion::for_each(e, LuaVisitor(state));
std::cout << "[Enemy] Name: " << e.name << ", health: " << e.health << ", family: " << e.family << ", level: " << e.level << std::endl;
lua_close(state);
return 0;
}
这将使您能够动态设置 Enemy
结构的成员,但是 boost
非常重量级,您需要保留 BOOST_FUSION_ADAPT_STRUCT
宏与实际结构保持同步。
luaaa
将 Enemy 对象直接映射到 lua(而不是传递一个表):#include <lua/luaaa.h>
struct Enemy
{
Enemy() {}
virtual ~Enemy() {}
void init(std::string _name, int _health, int _family, int _level) {
name = _name;
health = _health;
family = _family;
level = _level;
}
std::string name;
int health;
int family;
int level;
};
void myFunction(Enemy* e) {
std::cout << "[Enemy] Name: " << e->name << ", health: " << e->health << ", family: " << e->family << ", level: " << e->level << std::endl;
}
int main(int argc, char* argv[]) {
// init lua & bindings
lua_State* state = luaL_newstate();
luaaa::LuaClass<Enemy> luaEnemy(state, "Enemy");
luaEnemy
.ctor()
.fun("init", &Enemy::init);
luaaa::LuaModule mod(state, "sampleModule");
mod.fun("myFunction", myFunction);
luaL_dostring(state, R"(
enemy = Enemy.new()
enemy:init("My Enemy", 1, 2, 3)
sampleModule.myFunction(enemy)
)");
lua_close(state);
return 0;
}
然后就可以直接在lua中使用敌人对象了:
enemy = Enemy.new()
enemy:init("My Enemy", 1, 2, 3)
sampleModule.myFunction(enemy)
希望其中一个选项涵盖您的用例;)
关于c++ - 使用循环从外部文件填充结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/57382553/
我需要为打开的 xlsx 文件取消隐藏工作表 TAB,为此,我使用 VBS 文件打开 xlsm 文件并激活宏(位于模块中)。 当我手动运行宏时,它可以工作。 当它通过vbs激活时,它只能看到包含宏的x
我正在使用 Google Cloud Compute Engine 安装气流并使其保持正常运行。安装很好,现在它在主机上运行:0.0.0.0:8080 我有此 VM 实例的外部 IP 地址,但是我无法
我们可以在 GWT 中使用这个 $entry 方法来允许外部 javascript 执行 java 方法。 你可以在他们的文档 https://developers.google.com/web-to
在 Cython 的“Hello World”和 C 数学库中调用函数的示例之后 here ,我真正想做的是将我自己的 C 代码放在一个单独的文件中,并在 Cython 中使用它。关注 this ,我
我一直在试验 JSON Pointers引用和重用 JSON schemas . 按照示例,我能够引用在另一个 JSON 模式中声明的特定属性,一切都按预期进行,但是我还没有找到一种方法来扩展基本 J
我正在使用 X.jar 并添加到我的 AspectJ 项目(在 eclipse 中)。我已经为 X.jar 中的 myMethod() 方法编写了切入点和建议。 但是aspectj 并没有拦截这个方法
我正在 Controller 中创建一个自定义指令,并在 ng-repeat 中调用它,如下所示: HTML: JS: 在测试指令中,我按如下方式调用 loadDat
我正在尝试加载服务器上本地存在的 HTML 页面,位于名为 HTML-FIles 的文件夹中。 我想使用 jquery 加载一个文件并将其内容显示在 div 中。 现在,我可以加载文件,但在 div
我正在尝试根据初始选择从 JSON 文件生成选择菜单。我见过很多不同的方式,人们为此编写了一个函数,但想要一些非常简单的东西。 HTML: Please select Practis
我的目标是从 HTML 文档中获取文本,该文档不会调用 .jsp 文件中的任何函数。 我环顾四周,我以为我已经找到了问题的答案,但它似乎不起作用,其他答案包括使用 jQuery(我既不熟悉也不允许使用
我正在尝试从外部 JSON 文件获取文件内容,但我一直在警报中收到 null。 JS: function getText() { var result = null; var file
我正在加载一个外部 javascript 文件,该文件仅填充有 int 或字符串或 bool 值或数组的变量。类似... varBool=false; var1="var1"; var2="var2:
我的数据存储在外部 Javascript 文件中。 看起来像这样, window.videos = [{ "name": "Sample data", "duration": 154,
我有一个包含 Google ADWords 的 HTML 页面,以及来自外部 URL 的 ajax 调用,我想获取 json 来自 url 的数据。外部API也是我做的。API Controller
我试图看看是否有一种简单的方法可以通过外部 JavaScript 函数访问 Controller 的内部范围(与目标 Controller 完全无关) 我在这里看到了其他几个问题 angular.el
我尝试在运行外部命令时终止脚本,结果出现错误。考虑这个简单的代码: try { where.exe Test-App } catch { Write-Error "Exception
我在 test.js 中定义了一个外部 JS 函数 function InvokeSupport(ID, TimeStamp, Hash) { var sUrl = '' + "?uid="
如果我想将变量从外部 js 文件提取到另一个外部 js 文件。我该怎么做? 例如,如果我有一个名为 example1.js 的文件,其中包含以下代码 var test = 1; 如何获取变量 tes
我正在尝试使用 java 从外部 jar 中读取文件..例如,我有两个 jar 文件。一个是“foo.jar”,另一个是“bar.jar”。 “bar.jar”内部是文件“foo-bar.txt”。如
在我的 Java 应用程序中,我希望从未实际加载的类文件以及也未加载的 jar 文件中读取字节码内容。理想情况下,我需要能够获取任何给定的 jarfile,并找到其中的所有类。因此,考虑以下情况: 我
我是一名优秀的程序员,十分优秀!