【发布时间】:2016-11-18 18:14:25
【问题描述】:
我需要在我定义了 Lua 状态的主程序中为通过使用 SWIG 包装 c++ 代码创建的动态加载的 Lua 模块提供数据结构指针。
这是我的代码示例:
在 SimpleStruct.h 中:
#pragma once
struct SimpleStruct
{
int a;
double b;
};
在 exmaple.h(这个是用 SWIG 编译的)到 Lua 库:
#pragma once
#include "SimpleStruct.h"
#include <iostream>
class TestClass
{
public:
TestClass()
{
std::cout<<"TestClass created"<<std::endl;
}
~TestClass() {}
void ReadSimpleStruct(void * tmp)
{
std::cout<<"reading pointer: "<<std::endl;
SimpleStruct * pp = reinterpret_cast< SimpleStruct * >(tmp);
std::cout<<"Simple Struct: " << pp->a << " " << pp->b << std::endl;
}
};
仅在 example.cpp 中:
#include "example.h"
这是我的主程序(LuaTest.cpp):
extern "C"
{
#include <lua.h>
#include <lauxlib.h>
#include <lualib.h>
}
#include <iostream>
#include "SimpleStruct.h"
int main(int argc, char ** argv)
{
lua_State * L = luaL_newstate();
luaL_openlibs(L);
SimpleStruct * ss = new SimpleStruct();
ss->a = 1;
ss->b = 2;
lua_pushlightuserdata(L,ss);
lua_setglobal( L, "myptr");
int s = luaL_dostring(L, "require('example')");
s = luaL_dostring(L, "mc = example.TestClass()");
s = luaL_dostring(L, "mc:ReadSimpleStruct(myptr)");
if(s)
{
printf("Error: %s \n", lua_tostring(L, -1));
lua_pop(L, 1);
}
lua_close(L);
std::cout<<"done"<<std::endl;
return 0;
}
example.i(复制自 SWIG 中的 Lua 示例):
/* File : example.i */
%module example
%{
#include "example.h"
%}
/* Let's just grab the original header file here */
%include "example.h"
我将所有内容编译如下:
swig -c++ -lua example.i
g++ -c -fpic example.cpp example_wrap.cxx -I/usr/local/include -I/usr/include/lua5.2/
g++ -shared example.o example_wrap.o -o example.so
g++ LuaTest.cpp -o luatest -llua5.2 -I/usr/include/lua5.2/ -Wall
在 Ubuntu 16.04 上(和在 osx 上,具有不同的路径和相同的结果)。
在 Lua 脚本的最后一行我遇到了分段错误(当我尝试访问“mc:ReadSimpleStruct(myptr)”中的 pp->a 时)。
所以我的问题是:如何使用 Lua light userdata 向加载的 Lua 库提供指向 c++ 对象的指针?
一般来说:我的主程序中有一个包含游戏参数和对象的类,我想提供一个指向该类的指针,指向使用 SWIG 编译的其他加载的 Lua 库。
【问题讨论】:
-
你能把它做成一个真实的、完整的最小例子来展示它吗?我能理解的——我们需要知道“其他加载的 Lua 库”是如何工作的。
-
我认为,这是一个完整的真实示例:我使用 SWIG 将 TestClass 编译为名为“example”的 lua 库(这是“我的另一个 lua 库”),接下来在主程序中加载它库(通过“需要示例”)。接下来,我将创建一个 SimpleClass 结构的实例,并使用指向该实例的指针创建轻量级用户数据。最后,我希望能够通过 TestClass 对象('mc:ReadSimpleStruct(myptr))的方法从该指针读取数据。仅此而已,这将使我能够通过创建 SWIG 的 Lua 库访问我自己的全局参数。
-
您问题中的代码有很多
....。它甚至没有说明您的目标平台是什么。有一个名为 SimpleStruct.h 的文件,但包含 TestClass.h。没有 .i 文件。在我写下您未包含的所有缺失部分之前,我什至无法开始回答您的问题。我不知道你的目标是什么版本的 Lua。 -
好的,我已经编辑了我的问题并提供了整个代码。对于在第一个版本中没有提供完整信息,我深表歉意,但我认为问题出在我的 TestClass 声明中。
-
这看起来好多了 - 我会尝试在调试器中使用它,看看是否能找到解决方案。 (对于其他可能想要回答的人来说,他们也会发现它更容易)