C++ 在运行时使用C+中使用的脚本语言创建新类/成员+;
我断断续续地研究这个问题已经有几个月了,现在我真的想拿出一个合适的解决方案来处理在C++11项目的运行时使用成员函数/属性创建新的用户定义类(以及这些类的实例)的情况 到目前为止,我一直在使用SWIG(以前与Python一起使用,现在与Lua一起使用,探索Squirrel)。像我所遇到的所有C++绑定/嵌入库(Luna*,Luabter,LuabFin,OOLua,SqaDa/SqEXT,Surar)一样,所有的代码都希望在代码执行之前预定义C++类,因为它们要么依赖于预处理器指令或模板。 因此,我的问题是,是否有任何库使用更程序化的方法包装语言,或者有任何关于Lua或Squirrel之类的好教程/示例,可以推荐用于处理使用自定义成员和函数的自定义命名类的创建?如能提供一些指导,将不胜感激C++ 在运行时使用C+中使用的脚本语言创建新类/成员+;,c++,lua,swig,squirrel,C++,Lua,Swig,Squirrel,我断断续续地研究这个问题已经有几个月了,现在我真的想拿出一个合适的解决方案来处理在C++11项目的运行时使用成员函数/属性创建新的用户定义类(以及这些类的实例)的情况 到目前为止,我一直在使用SWIG(以前与Python一起使用,现在与Lua一起使用,探索Squirrel)。像我所遇到的所有C++绑定/嵌入库(Luna*,Luabter,LuabFin,OOLua,SqaDa/SqEXT,Surar)一样,所有的代码都希望在代码执行之前预定义C++类,因为它们要么依赖于预处理器指令或模板。 因此
甚至简单地展示了一个很好的例子,说明如何用一个函数和一个属性创建一个自定义类,在Lua、SyrReR中,通过它们各自的C++ API,不使用宏/模板/动态生成的代码,将是非常有帮助的。 编辑:我已经创建了一个
实例
类,该类包含成员键/值对的std::vector
,以及一个标识类型的成员,以便可以查找函数。然而,关于在Lua/Squirrel中创建简单类而不使用静态代码的文档很少
< >编辑2:我希望在任何平台上都能工作,而不必动态链接。< /P> < P>创建一个从现有C++类派生的类是我唯一的方法(把我自己)带进运行C++程序中。在动态编译实际C++源代码和加载生成的库时,物理上无法添加新的类。接下来最好的是在C++中创建一个代理对象,它包一个Python(Lua等)对象,并使该Python(Lua)对象成为一个类,该类扩展了一个现有的C++类,该类被镜像到Python(Lua)侧。
这是一个用Python扩展C++类的例子,使用Boosi::Python作为桥。 C++方面:
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
// this is the interface we will implement in Python
struct World
{
virtual std::string greet() = 0;
virtual ~World() {}
};
// this is a helper class needed to access Python-overrided methods
struct WorldWrap : World, wrapper<World>
{
std::string greet()
{
return this->get_override("greet")();
}
};
// This function tests our class implemented in Python
std::string test(World* w)
{
std::cout << "Calling w->greet() on some World-derived object\n";
return w->greet();
}
// This is what the Python side will see
BOOST_PYTHON_MODULE(hello)
{
class_<WorldWrap, boost::noncopyable>("World")
.def("greet", pure_virtual(&World::greet));
def("test", test);
}
考虑下面的Lua多重映射示例
Multimap={};
函数多重映射:\索引(键)
如果(键==“键”),则
本地ret={}
对于k,成对(自)do
ret[#ret+1]=k;
结束
返回ret;
其他的
返回rawget(getmetatable(self),键)
结束
结束
函数Multimap.Create()
局部自={};
可设置图元(自、多重映射);
回归自我;
结束
函数多重映射:插入(键、值)
本地列表=自[键];
如果(list==nil),则
列表={};
自[键]=列表;
结束
表.插入(列表、值);
结束
函数多重映射:删除(键、值)
本地列表=自[键];
断言(list~=nil,“找不到键”);
对于i=1,列出do
如果(列表[i]==值),则
表1.删除(列表一);
如果(#list==0),则
自[键]=零;
结束
返回;
结束
结束
错误(“未找到值”);
结束
--测试
m=Multimap.Create()
m:插入(1,5)
m:插入(2,6)
m:插入(3,7)
m:插入(1,8)
m:移除(2,6)
打印(pcall(函数()
m:Remove(2,6)——将产生断言异常
完)
打印(“键左:”,table.concat(m.keys,,'))
可以用C++实现这一点。
#包括
int多重映射索引(lua\U状态*L){
lua_settop(L,2);//强制2个参数
常量字符*key\u value=“key”;
大小键长度;
const char*key=lua_tolstring(L、2和key_len);
如果(!strncmp(key,key\u值,strlen(key\u值))){
int i=0;
lua_newtable(L);//堆栈:self,key,ret={}
int-ret=lua_gettop(L);
lua_pushnil(L);//堆栈:self,key,ret,nil
while(lua_next(L,1)!=0){//stack:self,key,ret,k,v
lua_pop(L,1);//堆栈:self,key,ret,k
lua_len(L,ret);//堆栈:self,key,ret,k,#ret
lua_pushvalue(L,-2);//堆栈:self,key,ret,k,#ret,k
lua_rawseti(L,ret,lua_tointeger(L,-2)+1);//ret[#ret+1]=k;|堆栈:self,key,ret,k,#ret
lua_pop(L,1);//堆栈:self,key,ret,k
}
//堆栈:self、key、ret
返回1;
}
否则{
lua_getmetatable(L,1);//堆栈:self,key,metatable(self)
lua_pushvalue(L,2);//堆栈:self,key,元表(self),key
lua_rawget(L,-2);//堆栈:self,key,metatable(self),rawget(metatable(self),key)
返回1;
}
}
int Multimap_Remove(lua_State*L){
lua_settop(L,3);//强制3个参数:self、key、value
lua_checkstack(L,12);//在堆栈上保留12个参数(以防万一)
lua_pushvalue(L,2);//堆栈:self,key,value,key
lua_gettable(L,1);//堆栈:self,key,value,list=self[key]
if(lua_isnil(L,-1))
luaL_错误(L,“未找到密钥”);
lua_len(L,-1);//堆栈:self、key、value、list、#list
整数计数=lua_tointeger(L,-1);
lua_pop(L,1);//堆栈:self、key、value、list
对于(inti=1;i免责声明:我将此贡献作为一个答案发布,因为我没有足够的声誉点数来添加评论
注释:抛开与特定脚本语言绑定的问题不谈,您似乎面临着C++
语言的一个基本限制:它不是“”(正如其他注释所指出的那样)。也就是说,语言d
#include <boost/python.hpp>
#include <iostream>
using namespace boost::python;
// this is the interface we will implement in Python
struct World
{
virtual std::string greet() = 0;
virtual ~World() {}
};
// this is a helper class needed to access Python-overrided methods
struct WorldWrap : World, wrapper<World>
{
std::string greet()
{
return this->get_override("greet")();
}
};
// This function tests our class implemented in Python
std::string test(World* w)
{
std::cout << "Calling w->greet() on some World-derived object\n";
return w->greet();
}
// This is what the Python side will see
BOOST_PYTHON_MODULE(hello)
{
class_<WorldWrap, boost::noncopyable>("World")
.def("greet", pure_virtual(&World::greet));
def("test", test);
}
import hello
class HomeWorld(hello.World):
""" Implements a function defined in C++ as pure virtual """
def greet(self):
return "howdy"
home = HomeWorld()
print (hello.test(home))