2013-08-26 9 views
5

के बिना एक सी ++ कक्षा को पाइथन में कैसे बेनकाब करना है, मैं जानना चाहता हूं कि सी ++ कक्षा को पाइथन में बेनकाब करने का कोई तरीका है लेकिन इंटरमीडिएट साझा लाइब्रेरी के निर्माण के बिना।एक मॉड्यूल

यहां मेरा वांछनीय परिदृश्य है। उदाहरण के लिए मैं सी निम्नलिखित है ++ वर्ग:

class toto 
    { 
    public: 
     toto(int iValue1_, int iValue2_): iValue1(iValue1_), iValue2(iValue2_) {} 
     int Addition(void) const {if (!this) return 0; return iValue1 + iValue2;} 

     private: 
     int iValue1; 
     int iValue2; 
    }; 

मैं किसी भी तरह के क्रम paremter (args) के रूप में यह भेजने के लिए आपका PyObject * करने के लिए (या इसके intance) इस वर्ग को परिवर्तित करना चाहते हैं, उदाहरण के लिए PyObject_CallObject रहे हैं:

PyObject* PyObject_CallObject(PyObject* wrapperFunction, PyObject* args) 

मेरी अजगर पक्ष में दूसरी ओर से, मैं एक wrapperFunction जो मेरे सी ++ वर्ग (या इसके उदाहरण) पैरामीटर के रूप में पर सूचक हो जाता होगा और वह अपने तरीकों कॉल या उसके गुण का उपयोग करता है:

def wrapper_function(cPlusPlusClass): 
    instance = cPlusPlusClass(4, 5) 
    result = instance.Addition() 

जैसा कि आप देख सकते हैं, मुझे वास्तव में एक अलग साझा लाइब्रेरी नहीं है या बूस्ट पायथन द्वारा मॉड्यूल का निर्माण नहीं करना है। मुझे जो कुछ चाहिए वह एक सी ++ कोड को PyObject में बदलने और इसे पायथन पर भेजने का तरीका ढूंढना है। मुझे सी पायथन पुस्तकालयों, बूस्ट या एसडब्ल्यूआईजी द्वारा ऐसा करने का कोई तरीका नहीं मिल रहा है।

क्या आपके पास कोई विचार है? आपकी मदद के लिए धन्यवाद।

+1

की उदाहरण मुझे यकीन है कि मैं वास्तव में आप क्या चाहते हैं समझ में नहीं कर रहा हूँ करने के लिए बात करने के लिए। Boost.Python 'boost :: पायथन :: ऑब्जेक्ट :: पीआरटी' है, जो 'PyObject *' देता है - क्या आप यही खोज रहे थे? –

+1

मेरा मानना ​​है कि सी/सी ++ को 'ctypes' के माध्यम से एक्सेस करना संभव है, लेकिन सी ++ कक्षा का पर्दाफाश करना मुश्किल हो सकता है। – Bakuriu

+0

@PaulManta: उत्तर के लिए धन्यवाद। जो मैं चाहता हूं वह 3 चरणों में होता है: चरण 1: PyObject सूचक में एक C++ कक्षा को समाहित करें। चरण 2 इस पॉइंटर को एक अजगर समारोह में भेजें। चरण 3। पायथन में इस सी ++ पॉइंटर का उपयोग करके (यानी इसके तरीकों को बुलावा)। तो क्या आप कृपया अधिक व्यावहारिक हो सकते हैं और एक उदाहरण के अनुसार बता सकते हैं कि मैं ऑब्जेक्ट :: पीआरटी में सी ++ कोड कैसे समाहित कर सकता हूं? –

उत्तर

1

मुझे मेरा जवाब मिला।

Exposing a C++ class instance to a python embedded interpreter

सी के बाद ++ वर्ग (! ध्यान डिफ़ॉल्ट निर्माता अनिवार्य है):

class TwoValues 
{ 
public: 
    TwoValues(void): iValue1(0), iValue2(0) {} 
    TwoValues(int iValue1, int iValue2): iValue1(iValue1_), iValue2(iValue2_) {} 

    int Addition(void) const {if (!this) return 0; return iValue1 + iValue2;} 

public: 
    int iValue1; 
    int iValue2; 
}; 

अवगत कराया जा सकता है वास्तव में मैं क्या खोज रहा था सुंदर क्या यह उत्तर (उसकी टिप्पणी के लिए धन्यवाद moooeeeep) के समान था निम्नलिखित मैक्रो द्वारा बढ़ावा द्वारा:

BOOST_PYTHON_MODULE(ModuleTestBoost) 
{ 
class_<TwoValues>("TwoValues") 
    .def("Addition",    &TWOVALUES::Addition) 
    .add_property("Value1",  &TWOVALUES::iValue1) 
    .add_property("Value2",  &TWOVALUES::iValue2); 
}; 

दूसरी ओर में मैं एक अजगर समारोह python_script.py whi में परिभाषित किया है ch इस वर्ग का एक उदाहरण लेता है और कुछ करता है।उदाहरण के लिए:

def wrapper_function(instance): 
    result = instance.Addition() 
    myfile = open(r"C:\...\testboostexample.txt", "w") 
    output = 'First variable is {0}, second variable is {1} and finally the addition is {2}'.format(instance.Value1, instance.Value2, result) 
    myfile .write(output) 
    myfile .close() 
सी ++ पक्ष में

फिर, मैं इस तरह एक ही समय में मेरी कक्षा का उदाहरण भेजने, द्वारा इस समारोह कॉल कर सकते हैं:

Py_Initialize(); 

try 
    { 
    TwoValues instance(5, 10); 
    initModuleTestBoost(); 

    object python_script = import("python_script"); 
    object wrapper_function = python_script.attr("wrapper_function"); 
    wrapper_function(&instance); 
    } 
catch (error_already_set) 
    { 
    PyErr_Print(); 
    } 

Py_Finalize(); 

लाभ:

  • मुझे किसी भी साझा लाइब्रेरी या बाइनरी
  • बनाने की आवश्यकता नहीं है क्योंकि मैं बूस्ट का उपयोग कर रहा हूं, मुझे स्मृति प्रबंधन के बारे में चिंता करने की आवश्यकता नहीं हैसंदर्भ
  • मैं साझा बढ़ावा सूचक का उपयोग नहीं करते गिनती (को बढ़ावा देने :: shared_ptr) मेरी कक्षा
6

जहाँ तक मुझे पता है, इसे पूरा करने का कोई आसान तरीका नहीं है।

सी ++ के साथ पायथन को न तो मॉड्यूल और न ही मध्यवर्ती पुस्तकालय के साथ विस्तारित करने के लिए, इसे गतिशील रूप से लाइब्रेरी लोड करने की आवश्यकता होगी, फिर फ़ंक्शंस आयात करना होगा। इस दृष्टिकोण का उपयोग ctypes मॉड्यूल द्वारा किया जाता है। सी ++ के साथ इसे पूरा करने के लिए, किसी को ctypes- लाइब्रेरी के साथ लिखने की आवश्यकता होगी जो लक्षित कंपाइलर के लिए C++ ABI को समझता है।

मॉड्यूल को पेश किए बिना पायथन का विस्तार करने के लिए, एक इंटरमीडिएट लाइब्रेरी बनाई जा सकती है जो सी + एपीआई प्रदान करता है जो सी ++ लाइब्रेरी को लपेटता है। इस इंटरमीडिएट लाइब्रेरी का उपयोग पाइथन में ctypes के माध्यम से किया जा सकता है। हालांकि यह सटीक कॉलिंग सिंटैक्स प्रदान नहीं करता है और एक इंटरमीडिएट लाइब्रेरी पेश करता है, यह ctypes- लाइब्रेरी के साथ सी ++ के साथ सीधे इंटरफेस कर सकता है, जो कि कम से कम प्रयास करेगा।

हालांकि, अगर इंटरमीडिएट लाइब्रेरी पेश की जा रही है, तो बूस्ट.पथन, एसडब्ल्यूआईजी, या कुछ अन्य सी ++/पायथन भाषा बाइंडिंग टूल का उपयोग करना उपयोगी हो सकता है। हालांकि इनमें से कई टूल मॉड्यूल के माध्यम से एक्सटेंशन पेश करेंगे, वे अक्सर क्लीनर कॉलिंग सम्मेलन प्रदान करते हैं, बाध्यकारी प्रक्रिया में बेहतर त्रुटि जांच करते हैं, और बनाए रखना आसान हो सकता है।

+0

बहुत अच्छा जवाब। मैं जो कुछ कहना चाहता था उसे कवर करता हूं और अधिक (इसलिए मैं जवाब देने वाला भी नहीं हूं;) – nneonneo

संबंधित मुद्दे