Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 为返回对向量的函数创建SWIG类型映射_C++_Lua_Swig_Typemaps - Fatal编程技术网

C++ 为返回对向量的函数创建SWIG类型映射

C++ 为返回对向量的函数创建SWIG类型映射,c++,lua,swig,typemaps,C++,Lua,Swig,Typemaps,我试图创建一个getter函数,它返回Lua中的对向量 我有以下C++中的矢量数据: {{1, "a"}, {2, "b"}, {3, "c"}} 我想将这个向量作为Lua中的表返回,以便它可以与Lua中的下表t相同: local t = {}; t[1].value = 1 t[1].name = "a" t[2].value = 2 t[2].name = "b" t[3].value = 3 t[3].name = "c" 这是我的密码: “MyBindings.h” “main.cp

我试图创建一个getter函数,它返回Lua中的对向量

我有以下C++中的矢量数据:

{{1, "a"}, {2, "b"}, {3, "c"}}
我想将这个向量作为Lua中的表返回,以便它可以与Lua中的下表
t
相同:

local t = {};
t[1].value = 1
t[1].name = "a"
t[2].value = 2
t[2].name = "b"
t[3].value = 3
t[3].name = "c"
这是我的密码:

MyBindings.h
main.cpp
我想要的结果: 我得到的结果: 向量:线程1:EXC\u坏访问(代码=1,地址=0x10)


如何更改代码以获得所需的结果?

基本上,解决方案是不使用输出参数(
argout
)。这实际上是C++编程的一般建议。在C时代,输出参数是必需的,因为在C时代,不能轻易地按值从函数返回数组

经过一点重构后,我最终得出以下结论:

MyBindings.h

#包括
#包括
#包括
类MyClass{
std::向量m_数据;
公众:
MyClass():m_数据({{1,a},{2,b},{3,c}}){}
std::vector data(){return m_data;}
};
MyBindings.i

%my模块
%{
#包括“MyBindings.h”
%}
%typemap(out)std::vector
{
新表(L);
对于(大小i=0;i<$1.size();++i)
{
新表(L);
lua_pushinteger(L,static_cast($1.at(i.first));
lua_设定域(L,-2,“值”);
lua_pushstring(L$1.at(i).second.c_str());
lua_集域(L,-2,“名称”);
卢厄·罗塞蒂(L,-2,i+1);
}
SWIG_arg++;
}
%包括“MyBindings.h”
main.cpp

#包括“lua.hpp”
外部“C”
{
国际卢奥彭州(卢奥州*L);
}
int main()
{
lua_State*L=luaL_newstate();
luaL_openlibs(L);
卢奥蓬(L);
lua_settop(L,0);
luaL_dostring(L,“local c=my.MyClass()\n”
“本地t=c:data()\n”
“打印('Value:'..t[2]。值)\n”
“打印('Name:'..t[2].Name)\n”);
卢厄关闭(L);
}
调用示例:

$swig-c++-lua MyBindings.i
$clang++-Wall-Wextra-Wpedantic-std=c++11-I/usr/include/lua5.3 MyBindings\u wrap.cxx main.cpp-llua5.3
美元/年
价值:2
姓名:b

(1)
*datap=MyData
内存泄漏,您可能需要
datap=&MyData
。(2) 您必须使用
argout
?从函数返回更容易。@HenriMenke我不必使用任何东西。只要它有效就可以了。然后它真的很容易解决。我很快会发布答案。顺便说一句,问题是
*datap=MyData
。您正在此处取消引用无效指针。但无论如何,你不应该使用这个解决方案,请参阅我的答案以获得替代方案。非常感谢你的回答。它就像一个符咒。明天我会给你一笔赏金。我发现即使在我从
MyBindings.I
中去掉
%include%include%include
后它仍然有效。这些包含是不必要的吗?@ZackLee这些只有在实际使用它们定义的类型映射时才是必要的。在这个简单的例子中,您只使用一个定义自己的单个类型映射,因此所有这些%都只是未使用。@ ZkLee实际上适用于任何包含,无论是在代码中> %>代码>在SWIG或<代码>中包含C++中的。如果您没有使用该标题中的任何内容,只需将其删除。@ZackLee,它只是从您的问题中复制和粘贴的,但是是的,它应该是
lua\u pushnumber
#include "main.h"

class MyClass
{
public:
    MyClass()
    :MyData({{1, "a"}, {2, "b"}, {3, "c"}}){}

    void getMyData(std::vector<pair<float, std::string>> *datap)
    {
        *datap = MyData;
    }
    std::vector<pair<float, std::string>> MyData;
};
%module my
%{
    #include "MyBindings.h"
%}

%include <stl.i>
%include <typemaps.i>
%include <std_string.i>
%include <std_vector.i>

/* convert the output std::vector<pair<float, std::string>> to lua_Table */
%typemap(in, numinputs = 0) (std::vector<pair<float, std::string>> *datap) 
(std::vector<pair<float, std::string>> *tdatap = nullptr) 
%{
%}
%typemap(argout) (std::vector<pair<float, std::string>> *datap) 
{
    lua_newtable(L);
    for (size_t i = 0; i < $1->size(); ++i)
    {
        lua_newtable(L);
        lua_pushinteger(L, static_cast<lua_Number>($1->at(i).first));
        lua_setfield(L, -2, "value");
        lua_pushstring(L, $1->at(i).second.c_str());
        lua_setfield(L, -2, "name");
        lua_rawseti(L, -2, i + 1);
    }
    SWIG_arg++;
}

%include "MyBindings.h"
#include "main.h"
#include "lua.hpp"

extern "C"
{
    int luaopen_my(lua_State *L);
}

int main()
{
    lua_State *L = luaL_newstate();
    luaL_openlibs(L);
    luaopen_my(L);
    lua_settop(L, 0);
    luaL_dostring(L, "local c = my.MyClass()\n"
                     "local t = c:getMyData()\n"
                     "print('Value : ' .. t[2].value)\n"
                     "print('Name : ' .. t[2].name)\n");
    lua_close(L);
}
Value : 2
Name : b