在C++中使用脚本语言在运行时创建新类/成员

我花了几个月的时间在处理这个问题,在一个C++11项目中,我想要一个真正的解决方案来处理创建在运行时创建新的用户定义类(和这些类的实例)与成员函数/属性的情况。

到目前为止,我一直在使用SWIG(以前是Python,现在是Lua,正在探索Squirrel).像我遇到的所有C++绑定/嵌入库(Luna*,luabinder,luabind,OOLua,Sqrat/Sqext,Squall),所有都希望在代码执行之前已经定义好你的类,因为它们要么依赖于预处理器指令,要么依赖于模板。

所以我的问题是,是否有任何库使用更过程化的方法来包装语言,或者是否有任何好的Lua或Squirrel的教程/示例,你会推荐处理创建自定义命名类与自定义成员和函数吗?一些指导将不胜感激。

即使有一个好的示例,显示如何使用它们各自的C++ API创建带有函数和属性的自定义类,而不使用宏/模板/动态生成的代码,也将非常有帮助。

编辑:我已经制作了一个Instance类,其中包含一个成员键/值对的std::vector和一个标识类型的成员,以便可以查找函数。然而,创建Lua/Squirrel中的简单类,没有使用静态代码,目前几乎没有任何文档。

编辑2:我希望有一个适用于任何平台且不必动态链接的解决方案。

点赞
用户775806
用户775806

在运行C++程序中创建一个新类的唯一方法(我所知道的)是从某个现有的C++类中派生出一个类。除了动态编译实际的C++源代码并加载生成的库之外,没有任何方法可以物理添加新类。接下来最好的方法是在C++中创建一个代理对象,其包装一个Python(Lua等)对象,并使该Python(Lua)对象成为扩展到Python(Lua)一侧的现有C++类的实例的类的实例。

        C++

     +---------+         mirrors                   +--------------+
     | class X |  ...............................> | class X      |
     +---------+                                   | mirrored to  |
          |                                        | Python       |
          | inherits                               +--------------+
          v                                      inherits  |
     +-----------------+                                   v
     | class X_Wrapper |        references         +--------------+
     |    | python obj ------------------------->  | class CX(X): |
     +-----------------+                           |    def met() |
                                                   +--------------+

以下是使用boost::python作为桥梁在Python中扩展C++类的示例。

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);
}

Python侧:

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))
2016-11-08 22:24:22
用户242106
用户242106

评论: 先抛开绑定某个脚本语言的问题,似乎你正在面对 C++ 语言的一个基本限制:它不是“动态的”(正如其他评论所指出的)。也就是说,该语言不提供任何功能来扩展或修改已编译的程序。

也许还没有失去所有的希望。在网上搜索“c++动态加载”会发现一些系统(如Linux和Windows)确实实现了动态加载机制。

以下是两篇(古老的)介绍该主题的文章的链接。

1.《Linux Journal》上的《C++ 在 Linux 上的动态类加载》。 2.《Dr.Dobb's》上的《动态加载的 C++ 对象》。

乍一看似乎很有趣。不过我不确定它们是否仍然相关。

这只是一次无保障的尝试。

2016-11-15 21:07:44