2

我正在玩弄将python用作我正在从事的项目的嵌入式脚本语言的想法,并且大多数事情都在工作。但是我似乎无法将 python 扩展对象转换回本机 c++ 指针。

所以这是我的课:

class CGEGameModeBase
{
public:
    virtual void FunctionCall()=0;
    virtual const char* StringReturn()=0;
};

class CGEPYGameMode : public CGEGameModeBase, public boost::python::wrapper<CGEPYGameMode>
{
public:
    virtual void FunctionCall()
    {
        if (override f = this->get_override("FunctionCall"))
            f();
    }

    virtual const char* StringReturn()
    {
        if (override f = this->get_override("StringReturn"))
            return f();

        return "FAILED TO CALL";
    }
};

增强包装:

BOOST_PYTHON_MODULE(GEGameMode)
{
    class_<CGEGameModeBase, boost::noncopyable>("CGEGameModeBase", no_init);

    class_<CGEPYGameMode, bases<CGEGameModeBase> >("CGEPYGameMode", no_init)
        .def("FunctionCall", &CGEPYGameMode::FunctionCall)
        .def("StringReturn", &CGEPYGameMode::StringReturn);
}

和python代码:

import GEGameMode

def Ident():
    return "Alpha"

def NewGamePlay():
    return "NewAlpha"


def NewAlpha():
    import GEGameMode
    import GEUtil

    class Alpha(GEGameMode.CGEPYGameMode):
        def __init__(self):
            print "Made new Alpha!"

        def FunctionCall(self):
            GEUtil.Msg("This is function test Alpha!")

        def StringReturn(self):
            return "This is return test Alpha!"

    return Alpha()

现在我可以通过这样做来调用第一个函数:

const char* ident = extract< const char* >( GetLocalDict()["Ident"]() );
const char* newgameplay = extract< const char* >( GetLocalDict()["NewGamePlay"]() );

printf("Loading Script: %s\n", ident);
CGEPYGameMode* m_pGameMode = extract< CGEPYGameMode* >( GetLocalDict()[newgameplay]() );

但是,当我尝试将 Alpha 类转换回其基类(上面的最后一行)时,我得到一个 boost 错误:

TypeError: No registered converter was able to extract a C++ pointer to type class CGEPYGameMode from this Python object of type Alpha

我在网上做了很多搜索,但无法弄清楚如何将 Alpha 对象转换为其基类指针。我可以将它保留为对象,而是将其作为指针,以便一些非 python 感知代码可以使用它。有任何想法吗?

4

3 回答 3

2

感谢 python c++ 邮件列表中的 Stefan,我失踪了

super(Alpha, self).__init__()

从构造函数调用意味着它永远不会成为父类。以为这会是自动的:D

我唯一遇到的其他问题是将新类实例保存为全局变量,否则它会在超出范围时被清理。

现在好开心

于 2009-08-31T13:00:16.370 回答
1

可能不是您正在寻找的答案,但请查看ChaiScript以嵌入到您的 C++ 应用程序中。

根据他们的网站,

ChaiScript 是第一个也是唯一一个从头开始设计并考虑到 C++ 兼容性的脚本语言。它是一种受 ECMAScript 启发的嵌入式函数式语言。

ChaiScript 没有元编译器,没有库依赖项,没有构建系统要求,也没有任何类型的遗留包袱。At 可以与您向其公开的任何 C++ 函数无缝协作。它不必明确告知任何类型,它是以功能为中心的。

使用 ChaiScript,您可以通过将三行代码添加到程序中来开始编写应用程序脚本,而根本不需要修改构建步骤。

于 2009-08-31T09:23:25.270 回答
0

好吧,我不确定它是否会帮助你,但我在 Lua 中遇到了同样的问题。我们从 Lua 创建了对象,并希望一些 c++ 代码通过指针来处理对象。我们做了以下事情:

  • 所有对象的东西都是用 C++ 编写的,包括构造函数、析构函数和工厂方法;
  • lua 代码调用工厂方法来创建对象。这个工厂方法 1) 给对象一个唯一的 ID 号,2) 在 c++ 映射中注册它,将 ID 号映射到本机指针;
  • 因此,每当 lua 要传递一个指向 c++ 代码的指针时,它都会给出一个对象 ID,而 c++ 代码会查找映射以通过 ID 找到实际的指针。
于 2009-08-31T09:22:47.940 回答