2012-07-11 10 views
8

से पाइथन कॉलबैक मेरे पास एक wx.py.Shell.shell विजेट है जो उपयोगकर्ता को मेरे प्रोग्राम के साथ इंटरैक्ट करता है जो पाइथन कोड निष्पादित करने देता है। मैं एक ऐसे फ़ंक्शन को पास करने में सक्षम होना चाहता हूं जिसे उपयोगकर्ता इस स्थान में मेरे सी ++ कोड (मेरे कस्टम विजेट के आसपास wxswig जेनरेट रैपर के माध्यम से) में परिभाषित करता है और इसे निष्पादित करता है।SWIG PyObject_Call सेगथन

मेरी सी ++ कोड मैं एक एसटीडी उपयोग कर रहा हूँ :: समारोह <> बाध्य कार्यों को लागू करने की कक्षा (सी ++ या अजगर) में

तो मैं समारोह कॉल ऑपरेटर के साथ PyObject रैप करने के लिए एक सरल वर्ग बनाया। हालांकि जब मैं PyObject * को कॉल करने का प्रयास करता हूं तो मुझे segfault मिलता है।

class PyMenuCallback 
{ 
    PyObject *Func; 
public: 
    PyMenuCallback(const PyMenuCallback &op2); 
    PyMenuCallback(PyObject *func); 
    ~PyMenuCallback(); 

    void operator() (int id); 
}; 
///////////////////////////////////////////////////////// 
PyMenuCallback::PyMenuCallback(PyObject *func) 
    : Func(func) 
{ 
    Py_XINCREF (Func); 
    if(!PyCallable_Check(Func)) 
     cout << "Not a Callable Callback." << endl; //Throw an exception or something 
} 

PyMenuCallback::PyMenuCallback(const PyMenuCallback &op2) 
    : Func (op2.Func) 
{ 
    Py_XINCREF (Func); 
    if(!PyCallable_Check(Func)) 
     cout << "Not a Callable Callback." << endl; 
} 

PyMenuCallback::~PyMenuCallback() 
{ 
    Py_XDECREF (Func); 
} 

void PyMenuCallback::operator() (int id) 
{ 
    cout << "Calling Callback" << endl; 
    if (Func == 0 || Func == Py_None || !PyCallable_Check(Func)) 
     return; 
    cout << "Building Args" << endl; 
    PyObject *arglist = Py_BuildValue ("(i)",id); 
    cout << "Func: " << Func->ob_type->tp_name << " " << Func->ob_refcnt << endl; 
    PyObject *result = PyObject_Call(Func,arglist,0); //<<<<<---SEGFAULTS HERE 
    cout << "Executed" << endl; 
    Py_DECREF(arglist); 
    Py_XDECREF(result); 
} 

क्या हो रहा था यह जानने के मेरे प्रयासों में, मैंने प्रिंट स्टेटमेंट का एक गुच्छा लगाया। जिसमें से एक प्रकार का नाम प्रिंट करता है और संदर्भ segfault से पहले लाइन को गिनता है। इसका परिणाम "फ़ंक्शन 3" में होता है, इसलिए मुझे लगता है कि फ़ंक्शन अभी तक नष्ट नहीं हुआ है।

मैं बड़ा घूँट के लिए निम्न गुजर रही है:

void AddOption (std::string name, PyObject *pycallback); 

जिसमें मैं क्या segfault पैदा करने के लिए एक नुकसान में एक PyMenuCallback

मैं का निर्माण, किसी भी विचार?

+1

शामिल करना सुनिश्चित करें मुझे लगता है कि आपने उल्लंघन किया है [तीन के नियम] (http://stackoverflow.com/questions/4172722 'PyMenuCallback' के लिए 'ऑपरेटर =' की आपूर्ति नहीं करके/किस चीज का नियम है। मुझे यकीन नहीं है कि यह समस्या है या नहीं, लेकिन यह निश्चित रूप से समस्याओं का कारण बनने की क्षमता है। – Flexo

+0

मैं इसे अपनी मशीन पर टेस्ट केस के साथ पुन: उत्पन्न करने में असमर्थ था। मैं पुष्टि करने में कामयाब रहा कि 'ऑपरेटर =' का उपयोग दुर्घटना से नहीं किया जा रहा है, लेकिन कोड ने काम किया और वाल्ग्रिंड से कोई चेतावनी उत्पन्न नहीं की। क्या आप अपने परीक्षण मामले को '% इनलाइन' और '% {%}' का उपयोग कर थोड़ा सा विस्तारित कर सकते हैं ताकि आप इसे एक इंटरफ़ेस फ़ाइल बना सकें? जैसे मैंने उपयोग किया: [यह] (http://pastebin.com/XYXj3a4p) परीक्षण करने के लिए जो आपके द्वारा उपयोग/रैपिंग का उपयोग कर सूक्ष्म मतभेद हो सकता है। – Flexo

+1

दरअसल, अच्छी पकड़, मैं ऑपरेटर भूल गया =। हालांकि इस समय इसका उपयोग नहीं किया जाता है, लेकिन मैं इसे जोड़ूंगा। – Tocs

उत्तर

3

के बाद से सी ++ अजगर कॉलबैक बुला एक wxWidget भीतर है, और बड़ा घूँट आवरण विशेष wxPython बड़ा घूँट द्वारा उत्पन्न होता है (wxswig?) कुछ धागा संरक्षण समारोह कॉल के आसपास की आवश्यकता है ...

निश्चित ऑपरेटर इस

void PyMenuCallback::operator() (int id) 
{ 
    cout << "Calling Callback" << endl; 
    if (Func == 0 || Func == Py_None || !PyCallable_Check(Func)) 
     return; 
    cout << "Building Args" << endl; 
    PyObject *arglist = Py_BuildValue ("(i)",id); 
    cout << "Built: " << arglist << endl; 
    cout << "Func: " << Func->ob_type->tp_name << " " << Func->ob_refcnt << endl; 

    wxPyBlock_t blocked = wxPyBeginBlockThreads(); //Anti-WxSwig 

    PyObject *result = PyObject_Call(Func,arglist,0); 

    wxPyEndBlockThreads(blocked); 


    cout << "Executed" << endl; 
    Py_XDECREF(arglist); 
    Py_XDECREF(result); 
} 

की तरह दिखना चाहिए

#include "wx/wxPython/wxPython.h" 
#include "wx/wxPython/wxPython_int.h" 
संबंधित मुद्दे