2015-06-02 18 views
6

W mojej szczególnej sytuacji mam złożoną klasę (klasa klas zajęć), którą chcę eksponować na język skryptowy (aka Ruby). Zamiast tego, że bezpośrednio przechodzą tę złożoną klasę, ktoś dał mi pomysł otwarcia kilku funkcji na język skryptowy, taki jak Ruby, który wydawał się prostszy. Widziałem Rice'a, ale jedyne przykłady, jakie widziałem, używają prostych funkcji, które po prostu mnożą coś, a nie łączą się z klasą.Wywołanie funkcji klasy C++ z Ruby/Python

Dla uproszczenia, Mam proste klasy z funkcji chcę wystawiać:

class Foo 
{ 
    private: 
     //Integer Vector: 
     std::vector<int> fooVector; 

    public: 
     //Functions to expose to Ruby: 
     void pushBack(const int& newInt) {fooVector.push_back(newInt);} 
     int& getInt(const int& element) {return fooVector.at(element);} 
}; 

TAKŻE:

wolałbym, aby nie tylko mieć link do strony pobierania SWIG lub artykuł wyjaśniający jak to zrobić z ryżem, który został napisany w 2010 roku, chciałbym przewodnik, który prawdopodobnie będzie działać (nie miałem dużo szczęścia jeszcze)

aswell:

Używam Linux (Ubuntu), ale jest to program cross-kompatybilne, więc muszę być w stanie skompilować na Windows i OS X

EDIT:

Rozumiem, że istnieją współdzielone biblioteki (dll i więc pliki), ale nie wiem, czy mogę mieć bibliotekę, która zależy od pliku .hpp zawierającego klasy (e).

+0

Po przeprowadzeniu badań, widziałem t Ruby może nie być najlepszym językiem do umieszczenia w C++. Jeśli tak, mogę zmienić pytanie, aby język skryptowy był Pythonem, jeśli ma to więcej sensu i nie unieważnia żadnych odpowiedzi. – bboy3577

+0

Możesz więc dodać tag python do pytania, aby przyciągnąć szczególną uwagę. – hedgesky

+0

@hedgesky Dzięki za przypomnienie, całkowicie zapomniałem o tym pytaniu, dopóki Orfby nie postawił nagrody. – bboy3577

Odpowiedz

2

Możesz użyć cython lub Boost.Python, aby wywołać natywny kod z Pythona. Ponieważ używasz C++, polecam zajrzeć do Boost.Python, która oferuje bardzo naturalny sposób pakowania klas C++ dla Pythona.

Jako przykład (zbliżony do tego, co podałeś), należy rozważyć następujące definicje klas

class Bar 
{ 
private: 
    int value; 

public: 
    Bar() : value(42){ } 

    //Functions to expose to Python: 
    int getValue() const { return value; } 
    void setValue(int newValue) { value = newValue; } 
}; 

class Foo 
{ 
private: 
    //Integer Vector: 
    std::vector<int> fooVector; 
    Bar bar; 

public: 
    //Functions to expose to Python: 
    void pushBack(const int& newInt) { fooVector.push_back(newInt); } 
    int getInt(const int& element) { return fooVector.at(element); } 
    Bar& getBar() { return bar; } 
}; 

double compute() { return 18.3; } 

To może być zawinięte do pytona użyciu Boost.Python

#include <boost/python.hpp> 
BOOST_PYTHON_MODULE(MyLibrary) { 
    using namespace boost::python; 

    class_<Foo>("Foo", init<>()) 
     .def("pushBack", &Foo::pushBack, (arg("newInt"))) 
     .def("getInt", &Foo::getInt, (arg("element"))) 
     .def("getBar", &Foo::getBar, return_value_policy<reference_existing_object>()) 
    ; 

    class_<Bar>("Bar", init<>()) 
     .def("getValue", &Bar::getValue) 
     .def("setValue", &Bar::setValue, (arg("newValue"))) 
    ; 

    def("compute", compute); 
} 

Kod ten może być skompilowany do biblioteka statyczna MyLibrary.pyd i używana w ten sposób

import MyLibrary 

foo = MyLibrary.Foo() 
foo.pushBack(10); 
foo.pushBack(20); 
foo.pushBack(30); 
print(foo.getInt(0)) # 10 
print(foo.getInt(1)) # 20 
print(foo.getInt(2)) # 30 

bar = foo.getBar() 
print(bar.getValue()) # 42 
bar.setValue(17) 
print(foo.getBar().getValue()) #17 

print(MyLibrary.compute()) # 18.3 
+0

To jest doskonałe, ale jedno, jak mam to zrobić dla normalnej funkcji zamiast funkcji klasy? – bboy3577

+0

Edytowane w tym przykładzie. Boost.Python jest naprawdę świetny, polecam sprawdzenie tej wiki, aby uzyskać więcej informacji: https://wiki.python.org/moin/boost.python – jornb87

0

Co z numerem Boost.Python?

Dlaczego nie chcesz używać SWIG?

+0

Nie mam nic przeciwko SWIG, właśnie powiedziałem, że nie chcę odpowiedzi, która brzmi "Oto X strona pobierania/dokumentacji, powodzenia!" Chcę "Tutaj jest biblioteka/narzędzie X, w ten sposób odsłaniasz dany kod źródłowy, a jest to przykład kodu Python/Ruby, który uzyskuje dostęp do' Foo :: pushBack (const int & newInt) '". (O Boost.Pythonie) Próbowałem używać bibliotek Boost, ale nigdy nie mogę używać bibliotek, które wymagają budowania (jak biblioteki Pythona). – bboy3577

+0

@ bboy3577 Rozumiem. Cóż, nigdy nie używałem Boost.Python i od lat nie używam SWIG, więc nie mogę podać niczego więcej niż przykłady w dokumentacji. Dokumentacja Boost.Python ma kilka dobrych przykładów. Odpowiedź wysłana przez jornb87 ma kilka przykładów kodu. –

+0

@ bboy3577 Ponadto, gdy mówisz: nie chcę odpowiedzi, która brzmi "Oto X strona pobierania/dokumentacji, powodzenia!" Chcę "Tutaj jest biblioteka/narzędzie X. W ten sposób ujawniasz dany kod źródłowy, a to jest przykładowy kod Python/Ruby, który uzyskuje dostęp do Foo :: pushBack (const int i newInt)" Po prostu wydaje się, że chcesz innych ludzi wykonywać dla ciebie pracę. O wiele lepiej, jeśli ludzie ci pomogą, jeśli pokażemy, co próbowaliście w SWIG/Boost.Python i błąd, który macie i co próbowaliście naprawić. –

Powiązane problemy