2012-01-27 10 views
8

मैं एक C++ लाइब्रेरी के लिए पाइथन रैपर बनाने के लिए SWIG 2.0 का उपयोग कर रहा हूं। एक विधि में "const std :: map &" प्रकार का तर्क है। SWIG खुशी से इसके लिए एक रैपर उत्पन्न करता है, लेकिन मैं समझ नहीं सकता कि विधि को कैसे बुलाया जाए। अगर मैं पास करता हूं, उदाहरण के लिए, उस तर्क के लिए {"a": "b"}, मुझे "NotImplementedError: गलत संख्या या अधिभारित फ़ंक्शन के लिए तर्कों का प्रकार" त्रुटि मिलती है।एसडब्ल्यूआईजी पाइथन में एक नक्शा <स्ट्रिंग, स्ट्रिंग> कैसे लपेटता है?

मैंने जेनरेट की गई .cxx फ़ाइल को आशा की उम्मीद में देखा कि यह स्पष्ट होगा, लेकिन ऐसा नहीं हुआ।

res4 = SWIG_ConvertPtr(obj3, &argp4, SWIGTYPE_p_std__mapT_std__string_std__string_t, 0 | 0); 
if (!SWIG_IsOK(res4)) { 
    SWIG_exception_fail(SWIG_ArgError(res4), "in method '" "new_Context" "', argument " "4"" of type '" "std::map< std::string,std::string > const &""'"); 
} 

यह स्पष्ट रूप से जानता है कि तर्क मौजूद है, और यह कुछ है कि एक नक्शे में परिवर्तित हो जाता होना चाहिए है कि: यहाँ कोड है कि उस तर्क को संसाधित करता है। लेकिन मैं यह नहीं समझ सकता कि वास्तव में मुझे इसके लिए क्या करना है।

+0

आप करने के लिए अपने बड़ा घूँट फ़ाइल में स्पष्ट रूप से नक्शे लपेट? मुझे लगता है कि आपको पाइथन कोड से सम्मिलित कॉल करके पॉप्युलेट के प्रकार का एक चर बनाने की आवश्यकता है। – mark

उत्तर

16

जब आप एक सी का उपयोग कर रहे ++ टेम्पलेट (उदाहरण के लिए एक std::map<string, string>) आप अजगर में उपयोग कर सकते हैं अपने .i फ़ाइल में इसके लिए एक उपनाम बनाने की जरूरत:

namespace std { 
%template(map_string_string) map<string, string>; 
} 

अब मान लीजिए कि आप करना चाहते हैं एक समारोह है कि इस तरह दिखता है लपेट:

void foo(const std::map<string, string> &arg); 

अजगर ओर, आप foo के लिए एक map_string_string, नहीं एक अजगर dict पारित करने के लिए की जरूरत है। ऐसा लगता है कि आप आसानी से एक अजगर dict एक नक्शा है, हालांकि ऐसा करने से परिवर्तित कर सकते हैं: तो

map_string_string({ 'a' : 'b' }) 

यदि आप foo कॉल करना चाहते हैं, तो आप इस सब करने की ज़रूरत:

foo(map_string_string({ 'a' : 'b' })) 

यहाँ पूर्ण उदाहरण है कोड जो काम करता है।

// test.i 
%module test 

%include "std_string.i" 
%include "std_map.i" 

namespace std { 
    %template(map_string_string) map<string, string>; 
} 

void foo(const std::map<std::string, std::string> &val); 

%{ 
#include <iostream> 
#include <string> 
#include <map> 

using namespace std; 
void 
foo(const map<string, string> &val) 
{ 
    map<string, string>::const_iterator i = val.begin(); 
    map<string, string>::const_iterator end = val.end(); 
    while (i != end) { 
     cout << i->first << " : " << i->second << endl; 
     ++i; 
    } 
} 

%} 

और अजगर परीक्षण कोड:

#run_test.py 
import test 

x = test.map_string_string({ 'a' : 'b', 'c' : 'd' }) 
test.foo(x) 

और मेरे आदेश पंक्ति:

% swig -python -c++ test.i 
% g++ -fPIC -shared -I/usr/include/python2.7 -o _test.so test_wrap.cxx 
% python run_test.py 
a : b 
c : d 
+0

यह मेरे लिए काम नहीं कर रहा है: map_string_string ({'a': 'b'}) वास्तव में वही त्रुटि उत्पन्न करता है जैसे '' a ':' b '}। क्या हो रहा है इसके बारे में अधिक जानकारी प्राप्त करने के लिए मैंने जेनरेट किए गए सी ++ कोड को हैक किया है, और इससे मुझे कोई समझ नहीं आती है। यद्यपि मैं पाइथन विधि में एक dict (या map_string_string) पास कर रहा हूं, फिर भी संबंधित तर्क के लिए पारित होने वाली PyObject एक कुंजी है जिसमें केवल कुंजी होती है। मान कहीं भी पारित नहीं लग रहे हैं। – peastman

+0

मैंने एक विस्तृत उदाहरण जोड़ा। कोशिश करके देखो। –

+0

ओह, मेरी गलती। (या बल्कि, उस व्यक्ति की गलती जिसने मूल रूप से एसडब्ल्यूआईजी कोड बनाया था।) यह पता चला कि कुछ तर्क सभी तर्कों को प्रीप्रोसेसिंग कर रहे थे, और यही वह है जो ताना को टुपल में बदल रहा था। – peastman

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