【问题标题】:Cross module dependencies in Boost PythonBoost Python中的跨模块依赖
【发布时间】:2011-05-25 06:32:29
【问题描述】:

假设我有两个定义如下的 boost python 模块。模块 A:

class SomeClass {
public:
    SomeClass() {}
    ~SomeClass() {}
};
BOOST_PYTHON_MODULE(A)
{   
    class_<SomeClass>("SomeClass");
}

和模块 B:

class AnotherClass {
public:
    AnotherClass() {}
    ~AnotherClass() {}
    void func(SomeClass& sp) {}
};
BOOST_PYTHON_MODULE(B)
{   class_<AnotherClass>("AnotherClass")
        .def("func", &AnotherClass::func)
    ;
}

模块 B 依赖于模块 A(即它使用来自模块 A 的 SomeClass)。现在,我执行以下 python 脚本:

import A
import B
obj1 = A.SomeClass()
obj2 = B.AnotherClass()
obj2.func(obj1)

我收到以下错误:

Traceback (most recent call last):
  File "C:\bladiebla\script.py", line 8, in <module>
    obj2.func(obj1)
ArgumentError: Python argument types in
AnotherClass.func(AnotherClass, SomeClass)
did not match C++ signature:
func(class AnotherClass {lvalue}, class SomeClass)

似乎 Python 不会自动在模块之间转换类。有谁知道如何解决这个问题?

【问题讨论】:

    标签: c++ python boost extension-modules


    【解决方案1】:

    我最近才开始摆弄 Boost.Python 并且遇到了同样的问题。

    查看以下文档的第 6 节:

    http://www.boost.org/doc/libs/1_47_0/libs/python/doc/building.html

    6.1 - 动态二进制

    该库包含一个类型转换注册表。 因为一个注册表在所有扩展模块之间共享,所以在一个动态加载的扩展模块中公开给 Python 的类的实例可以传递给在另一个此类模块中公开的函数

    我在使用静态二进制文件时遇到了与您遇到的相同类型的错误。一旦我更改为动态二进制文件,它就可以编译并运行良好。

    【讨论】:

      【解决方案2】:

      根据您在问题中的最新回复和更新的错误消息,我认为问题可能是因为您的 BOOST_PYTHON_MODULE 用法可能不正确(基于我在其他使用它的示例中看到的内容)。试试这样的方法,看看是否有帮助:

      模块 A:

      class SomeClass {
      public:
          SomeClass() {}
          ~SomeClass() {}
      };
      BOOST_PYTHON_MODULE(A)
      {   
          boost::python::class_<SomeClass>("SomeClass");
      }
      

      和模块 B:

      class AnotherClass {
      public:
          AnotherClass() {}
          ~AnotherClass() {}
          void func(SomeClass& sp) {}
      };
      BOOST_PYTHON_MODULE(B)
      {   boost::python::class_<AnotherClass>("AnotherClass")
              .def("func", &AnotherClass::func)
          ;
      }
      

      注意在两个BOOST_PYTHON_MODULE 声明中的每个class_&lt;...&gt; 语句中插入一个“boost::python::”前缀。

      【讨论】:

      • 您好,非常感谢您的反馈。但是,我想为两个没有继承关系的类解决这个问题。例如,您可以想象“SomeClass”实际上是“Triangle”类,而“AnotherClass”是“Polygon”类。我绝对不希望 Polygon 从 Triangle 继承,因为从 OO 的角度来看它没有意义。那么,我怎样才能在不同的模块中有两个类,它们不相互继承,但通过 Python 相互使用,就像我原来的例子一样?
      • func() 想要一个 SomeClass 参数。如果你想传递一些不同的东西,比如AnotherClass,你可以这样做AnotherClass继承SomeClass,方法是向SomeClass添加一个构造函数,将AnotherClass作为一个论点。或者,您可以只编写接受AnotherClass 参数并返回SomeClass 实例的内容,但必须显式调用它。如果你不能做这样的事情,那么我认为你被卡住了——如果通过了一些任意的类,它应该做什么func() 无论如何它一无所知?
      • 是的,我明白这一点,但我不想向这个函数传递任何不同的东西,只传递一个 SomeClass 类型的参数。在 python 脚本示例中,我的 obj1 是 A.SomeClass 类型。它与 B.AnotherClass 无关。 B.AnotherClass 中的 'func' 应该接受 A.SomeClass 类型的参数,例如 obj1。
      • 如果func() 接受AnotherClass 参数,则将其在模块B 中class AnotherClass 中的声明更改为void func(AnotherClass&amp; sp)——这是它的“C++ 签名”。之后obj2.func(obj1) 调用应该没问题。
      • PS,您可以像我建议的那样更改func() 的签名的唯一原因是因为它没有对它的论点做任何事情,因为它的 defined ( inline) 成为示例代码中的空函数{}。如果它访问了它的参数并试图用它做点什么,那么除非代码真的可以处理AnotherCLass 类型的对象,否则更改可能不会起作用。
      【解决方案3】:

      我遇到了类似的问题,并通过使用 boost::python::import() 函数从模块 B 导入模块 A 解决了它。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2010-09-14
        • 2014-08-28
        • 2019-02-11
        • 1970-01-01
        • 1970-01-01
        • 2015-06-23
        • 2015-12-28
        • 2016-09-24
        相关资源
        最近更新 更多