如何在LuaJIT FFI/C++绑定中使用shared_ptr?
2016-4-19 8:31:10
收藏:0
阅读:83
评论:1
我正在创建一个将Lua绑定到另一个C++项目的项目。经过一些调查,LuaJIT FFI似乎是实现该目标的最佳选择。我真的从lua用户邮件列表归档[1]和另一个相关幻灯片[2]中受益。实际上,这里已经完成了一个Hello World示例[3],并且欢迎提出改进建议。
目前,我正在尝试将shared_ptr引入到此示例中,以便我不需要担心垃圾收集问题。但由于我在Lua和LuaJIT上的经验不足,Lua脚本总是返回Segmentation fault,我甚至不知道如何调试。下面列出了代码段,并希望您这些有才华的人能给我一些实用的建议。
这是“hello.cpp”,我使用的命令来创建库是g++ -std=c++11 -shared -fPIC -o libhello.so hello.cpp。
#include<memory>
using namespace std;
class Hello {
public:
const char* World()
{
return "Hello World!\n";
}
};
typedef shared_ptr<Hello> pHello;
extern "C" {
pHello Hello_new(){
return pHello();
}
const char* Hello_World(pHello self){
return self->World();
}
}
这是“hello.lua”,运行命令是luajit hello.lua。
ffi = require('ffi')
ffi.cdef[[
typedef struct pHello pHello;
pHello Hello_new();
const char* Hello_World(pHello);
]]
hello = ffi.load('hello')
hello_index = {
World = hello.Hello_World
}
hello_mt = ffi.metatype('pHello', {
__index = hello_index
})
Hello = hello.Hello_new
hello = Hello()
io.write(ffi.string(hello:World()))
点赞
评论区的留言会收到邮件通知哦~
推荐文章
- 如何将两个不同的lua文件合成一个 东西有点长 大佬请耐心看完 我是小白研究几天了都没搞定
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
Things don't work like you expect them to do.
首先,你的 C++ 代码有缺陷:调用
return pHello()会返回一个空的shared_ptr,没有被管理的对象(即:空指针)。如果你想创建一个新的对象,请调用return std::make_shared< Hello >()。除此之外,使用
shared_ptr对垃圾回收并没有帮助。智能指针执行的引用计数依赖于析构函数的调用,这是一种 C++ 机制。由于 FFI 库与 C 代码进行交互,无论你如何包装它以传递给 LuaJIT,这都不会发生(你的编译器应该已经警告了你使用extern "C"与类类型的返回类型一起的情况)。标准的做法(如果你想依赖垃圾回收)是让
__gc元方法调用一个在 C++ 方面执行delete的函数。这是 C 的方法:你在函数调用中分配了一个资源,那么你就需要在之后负责释放它。我建议在你的类周围编写一个简单的包装器,可能首先使用纯 Lua API 来学习基础知识。当你拥有共享对象并不想亲自对其进行引用计数时,可以稍后再将其包装为
shared_ptr。