2012-03-30 12 views
24

मैं libev में गुजरने वाले तर्क की स्थिति में फंस गया हूं।लिबेव, प्रासंगिक कॉलबैक के लिए तर्क कैसे पास करें

आमतौर पर, libev संकुल एक समारोह में की तरह * receive_callback * प्राप्त करता है, तो कोई बात नहीं, लेकिन व्यवहार में, हम प्रेषण करने के लिए एक रिश्तेदार * write_callback * प्राप्त पैकेज के अनुसार विशिष्ट नौकरियों से निपटने के लिए की जरूरत है। उदाहरण के लिए:

S_RECV_MSG* pstRecvMsg = (S_RECV_MSG*) recv_buff; 
switch(pstRecvMsg->wMsgType) { 
    case 1: 
     ev_io_init(w, write_callback1, w->fd, EV_WRITE); 
     break; 
    case 2: 
     ev_io_init(w, write_callback2, w->fd, EV_WRITE); 
     break; 
    case 3: 
     // ....... 
} 

मेरा प्रश्न है, अगर write_callbackX भी recv_buff में विशिष्ट सामग्री को पढ़ने के लिए है, हम कैसे callbackX को recv_buff तर्क पारित कर सकते हैं? क्या हमें वैश्विक चर के बोझ और कुरूपता को सहन करना चाहिए?

+18

यह सही जवाब है, यदि आप चाहते हैं कि आप इसे वास्तविक उत्तर के रूप में लिख सकें और इसे स्वीकार कर सकें, तो अन्य लोगों के लिए जानकारी ढूंढना आसान हो जाता है। – dnaq

+3

कम से कम आप वापस गए और उत्तर के लिए चारों ओर इंतजार करने के बजाय शोध रखा ... :) खुशी है कि आपने इसे हल किया है। –

+15

मैं – Shahbaz

उत्तर

5

लेखक ने स्वयं को उत्तर दिया, लेकिन एक टिप्पणी में। चूंकि यह अनुत्तरित के रूप में दिखाई देता है, इसलिए मैं "उत्तर" अनुभाग में अपना उत्तर पोस्ट कर रहा हूं और लूप बंद कर रहा हूं। सुनिश्चित नहीं है कि कोई बेहतर तरीका है ... इसे ठीक करने में संकोच न करें।

प्रश्न लेखक का कहना है:

क्षमा करें, मैं अब मैं इस सवाल का जवाब मिल गया लगता है, और पढ़ने प्रलेखन की मेरी लापरवाही पर गहरा शर्म महसूस:

struct my_io{ 
    ev_io io; 
    int otherfd; 
    void *somedata; 
    struct whatever *mostinteresting; 
}; 
// ... 
struct my_io w; 
ev_io_init (&w.io, my_cb, fd, EV_READ); 

और फिर हम my_io तरह का उपयोग इस:

static void my_cb (struct ev_loop *loop, ev_io *w_, int revents) 
{ 
    struct my_io *w = (struct my_io *)w_; 
    //... 
} 
+0

में इसे संपादित करने के बजाय अपने समाधान को उत्तर के रूप में लिखने का सुझाव देता हूं (और फिर इसे स्वीकार करता हूं) अगर मैं somedata में हीप मेमोरी का उपयोग कर रहा हूं, तो इसे मुक्त करने का सही तरीका क्या है? –

+0

मुझे यह नहीं मिला। My_cb कॉलबैक में ev_io * w_ कैसे डाला जा सकता है (struct my_io *)? – lppier

+0

@lppier 'ev_io'' my_io' में पहला सदस्य है, इसलिए उसका पता उस कलाकार द्वारा प्राप्त किया जा सकता है। –

1

हाँ, यह है libev दस्तावेज़ में समझाया, और एक और तरीका है। प्रत्येक द्रष्टा एक शून्य * डेटा सदस्य है कि आप पढ़ सकते हैं या संशोधित कर सकते हैं, और libev पूरी तरह से इसे अनदेखा जाएगा है, तो आप इस तरह तर्क पारित कर सकते हैं:

w->data = (void *)recv_buff; 
... 
static void my_cb (struct ev_loop *loop, ev_io *w_, int revents) 
{ 
    S_RECV_MSG *recv_buff = (S_RECV_MSG*)w_->data; 
    ... 
} 

libev document देखते हैं।

+0

का उपयोग कर -> डेटा 'सबक्लासिंग' तकनीक की तुलना में ऐसा करने का एक मजेदार अच्छा तरीका है – matiu

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