2010-12-14 17 views
6

Załóżmy, że mam dwa moduły python doładowania, które są zdefiniowane następująco. Moduł A:Zależności między modułami w Boost Python

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

i modułu B:

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

module B jest zależny od modułu A (to znaczy używa SomeClass z modułu A). Teraz mogę wykonać następujący skrypt Pythona:

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

pojawia się następujący błąd:

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) 

Wydaje się, że Python nie przekładają się automatycznie klas między modułami. Czy ktoś ma pomysł, jak to rozwiązać?

Odpowiedz

0

Na podstawie ostatniej odpowiedzi i zaktualizowanego komunikatu o błędzie w pytaniu, prawdopodobnie problem może wynikać z tego, że korzystanie z BOOST_PYTHON_MODULE może być nieprawidłowe (na podstawie tego, co widziałem w innych przykładach korzystania z niego). Spróbuj coś takiego i zobacz czy to pomaga:

Moduł A:

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

I Moduł B:

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

Uwaga wkładanie o "boost::python::" prefiksu na rachunku w każdym class_<...> z dwóch deklaracji BOOST_PYTHON_MODULE.

+0

Witam, dziękuję bardzo za Twoją opinię. Jednak chciałbym rozwiązać ten problem dla dwóch klas, które nie mają związku spadkowego. Na przykład można sobie wyobrazić, że "SomeClass" jest w rzeczywistości klasą "Triangle", a "AnotherClass" to klasa "Polygon". Zdecydowanie nie chcę, aby Wielokąt dziedziczył z Trójkąta, ponieważ nie ma sensu z punktu widzenia OO. Jak więc mogę mieć dwie klasy w różnych modułach, które nie dziedziczą się od siebie nawzajem, ale które wykorzystują się nawzajem za pośrednictwem Pythona, tak jak w moim oryginalnym przykładzie? – Arjan

+0

'func()' chce argumentu 'SomeClass'. Jeśli chcesz przekazać mu coś innego, np. 'AnotherClass', możesz to zrobić ** bez ** uczynienia' AnotherClass' dziedziczącym po 'SomeClass' przez dodanie konstruktora do' SomeClass' który bierze 'AnotherClass' jako argument. Alternatywnie możesz po prostu napisać coś, co zaakceptuje argument "AnotherClass" i zwróci instancję 'SomeClass', ale będzie musiał ją jawnie nazwać.Jeśli nie możesz zrobić czegoś takiego, to myślę, że utknąłeś - co i tak ma robić 'func(), jeśli przeszedł jakąś dowolną klasę, o której nic nie wie? – martineau

+0

Tak, rozumiem to, ale nie chcę przekazać nic innego do tej funkcji, tylko argument typu SomeClass. W przykładzie skryptu Pythona moje obj1 ma typ A.SomeClass. Nie ma związku z B.AnotherClass. "func" w B.AnotherClass powinien akceptować parametry typu A.SomeClass, takie jak obj1. – Arjan

6

Niedawno zacząłem grać z Boost.Pythonem i miałem ten sam problem.

Zapoznaj się punkt 6 o następującym dokumencie:

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

6.1 - Dynamic Binary

Biblioteka zawiera rejestr typu konwersji. Ponieważ jeden rejestr jest współużytkowany przez wszystkie moduły rozszerzeń, wystąpienia klasy wystawionej na działanie Pythona w jednym dynamicznie ładowanym module rozszerzeń można przekazać do funkcji ujawnionych w innym takim module.

Użyłem statycznego pliku binarnego i otrzymałem ten sam typ błędu, który otrzymywałeś. Po zmianie na dynamiczny plik binarny został skompilowany i działał poprawnie.

Powiązane problemy