Cross module dependencies in Boost Python

2019-02-13 11:29发布

问题:

Suppose I have two boost python modules that are defined as follows. Module A:

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

And module B:

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

Module B has a dependency on module A (i.e. it uses SomeClass from module A). Now, I execute the following python script:

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

I get the following error:

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)

It seems that Python does not automatically translate classes between modules. Does anyone have an idea how to solve this?

回答1:

I just recently started fiddling with Boost.Python and had the same problem.

Check out section 6 of the following doc:

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

6.1 - The Dynamic Binary

The library contains a type conversion registry. Because one registry is shared among all extension modules, instances of a class exposed to Python in one dynamically-loaded extension module can be passed to functions exposed in another such module.

I was using the static binary and got the same type of error you were getting. Once I changed to the dynamic binary, it compiled and ran fine.



回答2:

Based on your latest response and updated error message in your question, I think the problem might be because your BOOST_PYTHON_MODULE usage might be incorrect (based on what I've seen in other examples of using it). Try something like this and see if it helps:

Module A:

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

And module B:

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

Note the insertion of a "boost::python::" prefix onto the class_<...> statement in each of the two BOOST_PYTHON_MODULE declarations.