SWIG

2012-11-07 10 views
11

का उपयोग करके enum सदस्यों को कैसे समझाएं I क्या मैं एक सी ++ enum को स्थिरांक के सेट की बजाय वास्तविक इकाई के रूप में एसडब्ल्यूआईजी का पर्दाफाश कर सकता हूं ताकि मैं उनके ऊपर पायथन कोड में गणना कर सकूं?SWIG

उत्तर

10

मुझे एक ही समस्या का सामना करना पड़ा। मुझे उम्मीद है कि एसडब्ल्यूआईजी जल्द ही सी ++ 11 के enum class का समर्थन करता है।

यहाँ एक हैक कि बड़ा घूँट मना एक संरचना में enums डाल करने के लिए है:

#ifdef SWIG 
%rename(MyEnum) MyEnumNS; 
#endif 

struct MyEnumNS 
{ 
    enum Value { Value1, Value2, Value3 }; 
}; 
typedef MyEnumNS::Value MyEnum; 

.cpp में कोड अब आप MyEnum::Value1 का उपयोग करना चाहिए और अजगर कोड में यह MyEnum.Value1 है। हालांकि संकलित, typedef मौजूदा कोड को बदलने से रोकता है जो हर जगह enum का उपयोग करता है और SWIG% नामकरण enum के समान SWIG wrapper में समान नाम बनाता है।

अजगर में आप एक छोटे से कोड के साथ मूल्यों की गणना कर सकते हैं:

def values(enum): 
    return [(k,v) for k,v in vars(enum).items() if isinstance(v,int)] 

यह बहुत नहीं है, और मैं एक बेहतर समाधान को देखने के लिए अच्छा लगेगा।

+0

हाँ, मैं कुछ इस तरह के बारे में सोच रहा था, लेकिन आपका जवाब कुछ, पैटर्न का उपयोग करने के लिए तैयार धन्यवाद प्रदान करता है। क्या आप कृपया उल्लेख किए गए 'आकार' मुद्दे पर थोड़ा और बता सकते हैं? कौन सा कोड बिल्कुल तोड़ सकता है, क्योंकि मुझे काफी कुछ नहीं मिलता है। – unkulunkulu

+0

मैं उस भाग को हटा दूंगा।यह कुछ ऐसा था जो मैं कार्यान्वयन खोजने की कोशिश करते समय विचार कर रहा था, लेकिन मैंने अभी इसे फिर से देखा और वास्तव में कोई मुद्दा नहीं था। –

2

मैं यकीन है कि आप देख रहे हैं कर रहे हैं हूँ ...
typemaps: चूंकि प्रकार से निपटने इतना आवरण कोड पीढ़ी के लिए महत्वपूर्ण है, बड़ा घूँट की अनुमति देता है यह पूरी तरह से उपयोगकर्ता द्वारा परिभाषित किया जा करने के लिए (या नए सिरे से परिभाषित)। ऐसा करने के लिए, एक विशेष% टाइपमैप निर्देश का उपयोग किया जाता है। (SWIG Doc2.0)

सभी जानकारी के लिए आपको यहां टाइपमैप के बारे में कभी भी आवश्यकता हो सकती है, इसके बारे में SWIG दस्तावेज़ का लिंक है। http://www.swig.org/Doc2.0/Typemaps.html#Typemaps_nn2

टाइपपेप्स आपको सीआईआईजी को सी ++ एनम्स को पाइथन ऑब्जेक्ट्स में कनवर्ट करने के लिए कहने की अनुमति देनी चाहिए।

+0

@ फ्लेक्सो, टीबीएच, मुझे टाइपमैप के बारे में पता नहीं था, मैं एसडब्ल्यूआईजी के लिए नया हूं, उन्होंने इसे अभी कुछ गहरे हिस्सों में एक परियोजना पर इस्तेमाल किया है, यह काम करता है और कोई भी परवाह नहीं करता है, लेकिन फिर मैंने इसे विस्तारित करने का फैसला किया बिट। – unkulunkulu

5

हम कुछ ऐसा कर सकते हैं जो आपको पाइथन में इसके बारे में बताए, सी ++ शीर्षकों में अपेक्षाकृत कम घुसपैठ के साथ यह लपेटता है।

#ifndef PYTHON_ENUM 
#define PYTHON_ENUM(x) enum x 
#endif 

PYTHON_ENUM(TestName) { 
    foo=1, 
    bar=2 
}; 

PYTHON_ENUM(SomeOtherName) { 
    woof, 
    moo 
}; 

यह सिर्फ सी ++ में एक नियमित रूप से enum होने के लिए फैलता है, लेकिन एक हेडर फाइल अजगर में enum सदस्यों को बेनकाब करने के रूप में पर्याप्त है: उदाहरण के लिए हम एक हेडर फाइल है।

%typemap(constcode) का उपयोग करके हम enum के लिए हमारे पायथन मॉड्यूल में कुछ अतिरिक्त चीजें इंजेक्ट कर सकते हैं, लेकिन हमें ऐसा करने के लिए enum का नाम जानना होगा; इसके लिए SWIG टाइपइन्फो ऑब्जेक्ट जैसा है कि यह int था। इसलिए हम कस्टम टाइपमैप में enum का नाम संग्रहीत करने के लिए हमारे PYTHON_ENUM मैक्रो में एक हैक का उपयोग करते हैं।

%module test 
%{ 
#include "test.h" 
%} 

%typemap(constcode) int { 
    PyObject *val = PyInt_FromLong(($type)($value)); 
    SWIG_Python_SetConstant(d, "$1", val); 
    const char *name = "$typemap(enum_realname,$1_type)"; 
    PyObject *e = PyDict_GetItemString(d, name); 
    if (!e) PyDict_SetItemString(d, name, e = PyDict_New()); 
    PyDict_SetItemString(e, "$value", val); 
} 
#define PYTHON_ENUM(x) \ 
     %typemap(enum_realname) int "x"; \ 
     %pythoncode %{ \ 
     x = _test.x\ 
     %} \ 
     enum x 

%include "test.h" 

यह कुंजी/मूल्य जोड़े वाले प्रत्येक enum के लिए मध्यवर्ती मॉड्यूल में एक PyDict बनाता है। उजागर मॉड्यूल में इंटरमीडिएट मॉड्यूल में PyDict को बांधने के लिए वहां कुछ %pythoncode गोंद भी है। (मुझे यकीन नहीं है कि इंटरमीडिएट मॉड्यूल को उस नाम से कैसे संदर्भित किया जाए, हार्डकोडेड के अलावा _test - आवश्यकतानुसार बदलें)।

यह पर्याप्त है कि मैं तो के रूप में उपयोग कर सकते हैं:

Python 2.7.3 (default, Aug 1 2012, 05:16:07) 
[GCC 4.6.3] on linux2 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import test 
>>> print test.SomeOtherName 
{'woof': 0, 'moo': 1} 
>>> print test.TestName 
{'foo': 1, 'bar': 2} 
>>> 
+0

तो ऐसा लगता है कि एसडब्ल्यूआईजी उद्देश्य पर सरल होने का नतीजा यह है कि ऐसा लगता है कि उन्हें स्क्रिप्टिंग भाषाओं में सी/सी ++ प्रतिबिंब लाने की ज़रूरत नहीं है, बस इंटरफेस पीढ़ी। ऐसा लगता है कि मुझे मार्क टोलोनन के समाधान के साथ जाना होगा क्योंकि कुछ आपके बारे में समझेंगे, हालांकि मैं इसे समझने के किनारे पर हूं: डी टाइपमैप के साथ चीजों की कोशिश करने के उदाहरण के लिए धन्यवाद। – unkulunkulu

+0

@unkulunkulu - आम तौर पर एसडब्ल्यूआईजी सी (या सी ++) में जो कुछ भी कर सकता है उसे करने में आसान बनाता है, लेकिन उससे परे भटकना कठिन होता है। – Flexo

+0

@ फ्लेक्सो अच्छा समाधान। मैंने इसे एक शब्दकोश आयात करने के लिए थोड़ा बढ़ाया, जो कुंजी पर डॉट पूर्णता का समर्थन करता था और 'x = _test.x' को' x = dotdict (_test.x) 'के साथ बदल दिया गया था और dicts आयात dotdict% से '% pythoncode% {जोड़ा } 'PYTHON_ENUM' मैक्रो से पहले। –

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