2012-01-23 10 views
5

मुझे .dll साझा लाइब्रेरी से एसडब्ल्यूआईजी इंटरफ़ेस के साथ निर्यात किए गए कार्यों का उपयोग करने में समस्या आ रही है।विंडोज़ से SWIG wrapped फ़ंक्शंस का उपयोग करना। डीएल

Version Info

Python: 2.6.4

Swig: 2.0.4

बड़ी तस्वीर है: मैं सी ++ का उपयोग करते हुए लिनक्स के तहत विकसित कुछ कोड है और बड़ा घूँट का उपयोग कर लपेटा। मैंने सी ++ स्रोत को लिनक्स के तहत .so ऑब्जेक्ट में संकलित किया और पाइथन में .so लाइब्रेरी का उपयोग किया।

अब, मुझे इन सभी कार्यों को विंडोज़ में माइग्रेट करने की आवश्यकता है और विंडोज़ में .so के लिए समकक्ष .dll है। इसलिए, मैंने सभी सी ++ स्रोत कोड को .dll में संकलित करने और पायथन के माध्यम से उन्हें एक्सेस करने की योजना बनाई।

तो सामान्य प्रक्रिया होगी: सी ++ स्रोत -> उन्हें SWIG का उपयोग करके लपेटें ->.dll -> पायथन के माध्यम से संकलित करें।

एसडब्ल्यूआईजी का उपयोग करके उत्पन्न एक बड़ी .cxx स्रोत फ़ाइल है जिसमें मैंने विकसित किए गए सभी कार्यों को शामिल किया है। कार्य अब इस SWIG जेनरेट की गई फ़ाइल को .dll में संकलित करना है ताकि मैं बाद में सभी कार्यों का उपयोग कर सकूं। हालांकि, .cxx फ़ाइल मेरे सभी कार्यों को लपेटने के कुछ अजीब तरीके का उपयोग करती है और मुझे कोई संकेत नहीं है कि उनका उपयोग कैसे किया जाए।

फ़ंक्शंस निम्नानुसार लपेटे गए हैं। Ssay मैं एक सी ++ वर्ग sdrts_reverse_burst_ff कहा जाता है, लपेटकर के बाद, वर्ग .cxx फ़ाइल में एक समारोह हो जाता है और इस तरह परिभाषित किया गया है है:

SWIGINTERN PyObject *_wrap_sdrts_reverse_burst_ff_sptr___deref__(PyObject *SWIGUNUSEDPARM(self), PyObject *args) { 

PyObject *resultobj = 0; 

boost::shared_ptr<sdrts_reverse_burst_ff> *arg1 = (boost::shared_ptr<sdrts_reverse_burst_ff> *) 0 ; 

    void *argp1 = 0 ; 

    int res1 = 0 ; 

    PyObject * obj0 = 0 ; 

    sdrts_reverse_burst_ff *result = 0 ; 



    if(!PyArg_UnpackTuple(args,(char *)"sdrts_reverse_burst_ff_sptr___deref__",1,1,&obj0)) SWIG_fail; 

    res1 = SWIG_ConvertPtr(obj0, &argp1,SWIGTYPE_p_boost__shared_ptrT_sdrts_reverse_burst_ff_t, 0 | 0); 

    if (!SWIG_IsOK(res1)) { 

    SWIG_exception_fail(SWIG_ArgError(res1), "in method '" "sdrts_reverse_burst_ff_sptr___deref__" "', argument " "1"" of type '" "boost::shared_ptr<sdrts_reverse_burst_ff> *""'"); 

    } 

    arg1 = reinterpret_cast< boost::shared_ptr<sdrts_reverse_burst_ff> * >(argp1); 

    result = (sdrts_reverse_burst_ff *)(arg1)->operator ->(); 

    resultobj = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_sdrts_reverse_burst_ff, 0 | 0); 

    return resultobj; 

fail: 

    return NULL; 

} 

यही नहीं: इस .cxx फ़ाइल के अंत के पास एक विशाल सरणी है जो सभी दर्जे के प्रकार्य इस तरह शामिल हैं:

PyMethodDef SwigMethods[] = { 

    { (char *)"sdrts_reverse_burst_ff_sptr___deref__", _wrap_sdrts_reverse_burst_ff_sptr___deref__, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr___deref__(sdrts_reverse_burst_ff_sptr self)"}, 

    { (char *)"delete_sdrts_reverse_burst_ff_sptr", _wrap_delete_sdrts_reverse_burst_ff_sptr, METH_VARARGS, (char *)"delete_sdrts_reverse_burst_ff_sptr(sdrts_reverse_burst_ff_sptr self)"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_set_reverse_burst", _wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_set_reverse_burst(sdrts_reverse_burst_ff_sptr self, int samples) -> int"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_enable_reverse_burst", _wrap_sdrts_reverse_burst_ff_sptr_enable_reverse_burst, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_enable_reverse_burst(sdrts_reverse_burst_ff_sptr self) -> int"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_reset", _wrap_sdrts_reverse_burst_ff_sptr_reset, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_reset(sdrts_reverse_burst_ff_sptr self) -> int"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_history", _wrap_sdrts_reverse_burst_ff_sptr_history, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_history(sdrts_reverse_burst_ff_sptr self) -> unsigned int"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_output_multiple", _wrap_sdrts_reverse_burst_ff_sptr_output_multiple, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_output_multiple(sdrts_reverse_burst_ff_sptr self) -> int"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_relative_rate", _wrap_sdrts_reverse_burst_ff_sptr_relative_rate, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_relative_rate(sdrts_reverse_burst_ff_sptr self) -> double"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_start", _wrap_sdrts_reverse_burst_ff_sptr_start, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_start(sdrts_reverse_burst_ff_sptr self) -> bool"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_stop", _wrap_sdrts_reverse_burst_ff_sptr_stop, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_stop(sdrts_reverse_burst_ff_sptr self) -> bool"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_nitems_read", _wrap_sdrts_reverse_burst_ff_sptr_nitems_read, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_nitems_read(sdrts_reverse_burst_ff_sptr self, unsigned int which_input) -> uint64_t"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_nitems_written", _wrap_sdrts_reverse_burst_ff_sptr_nitems_written, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_nitems_written(sdrts_reverse_burst_ff_sptr self, unsigned int which_output) -> uint64_t"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_detail", _wrap_sdrts_reverse_burst_ff_sptr_detail, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_detail(sdrts_reverse_burst_ff_sptr self) -> gr_block_detail_sptr"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_set_detail", _wrap_sdrts_reverse_burst_ff_sptr_set_detail, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_set_detail(sdrts_reverse_burst_ff_sptr self, gr_block_detail_sptr detail)"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_name", _wrap_sdrts_reverse_burst_ff_sptr_name, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_name(sdrts_reverse_burst_ff_sptr self) -> string"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_input_signature", _wrap_sdrts_reverse_burst_ff_sptr_input_signature, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_input_signature(sdrts_reverse_burst_ff_sptr self) -> gr_io_signature_sptr"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_output_signature", _wrap_sdrts_reverse_burst_ff_sptr_output_signature, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_output_signature(sdrts_reverse_burst_ff_sptr self) -> gr_io_signature_sptr"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_unique_id", _wrap_sdrts_reverse_burst_ff_sptr_unique_id, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_unique_id(sdrts_reverse_burst_ff_sptr self) -> long"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_to_basic_block", _wrap_sdrts_reverse_burst_ff_sptr_to_basic_block, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_to_basic_block(sdrts_reverse_burst_ff_sptr self) -> gr_basic_block_sptr"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_check_topology", _wrap_sdrts_reverse_burst_ff_sptr_check_topology, METH_VARARGS, (char *)"sdrts_reverse_burst_ff_sptr_check_topology(sdrts_reverse_burst_ff_sptr self, int ninputs, int noutputs) -> bool"}, 

    { (char *)"sdrts_reverse_burst_ff_sptr_swigregister", sdrts_reverse_burst_ff_sptr_swigregister, METH_VARARGS, NULL}, 

    { (char *)"reverse_burst_ff", _wrap_reverse_burst_ff, METH_VARARGS, (char *)"reverse_burst_ff(int max_samples) -> sdrts_reverse_burst_ff_sptr"}, 

    { NULL, NULL, 0, NULL } 

}; 

मैं .dll रों साथ मेरे पुराने अनुभव पीछा किया और एक सरल __declspec(dllexport) सिर के साथ सभी कार्यों का निर्यात किया। फिर भी

import ctypes 

_dll_func_list = ctypes.WinDLL("func.dll") 

_reverse_burst_ref = _dll_func_list._wrap_sdrts_reverse_burst_ff_sptr___deref__ 

, कि दूर का मैं दृष्टिकोण कर सकते हैं: अजगर में, मैं भी _wrap_sdrts_reverse_burst_ff_sptr___deref__ मैं निर्यात कॉल कर सकते हैं। जब मैं उप काम करता है, उदाहरण के लिए, कि कक्षा में पहुँचने का प्रयास

_class_ref._wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst(0) 

शापित मशीन मुझसे कहा:

'_wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst' cannot be found.

जब मैं समारोह सीधे कॉल और इस तरह एक पैरामीटर में पारित करने के लिए कोशिश :

_dll_func_list ._wrap_sdrts_reverse_burst_ff_sptr_set_reverse_burst(0) 

मशीन का कहना है

WindowsError: exception: access violation reading 0x00000004

क्या किसी को पता है कि पाइथन का उपयोग करके निर्यात किए गए एसडब्ल्यूआईजी लिपटे कार्यों का उपयोग कैसे किया जाए?

उत्तर

2

एसडब्ल्यूआईजी .cxx फ़ाइल के अलावा, एक .py फ़ाइल भी उत्पन्न करता है।एक बार जब आप अपने मंच पर एक DLL बनाया (या साझा वस्तु) किया है सब आप उपयोग करना है कि अजगर अपने आप में क्या करने की जरूरत

import ModuleName 

वह जगह है जहाँ ModuleName है क्या आप में बड़ा घूँट बताया मॉड्यूल कॉल करने के लिए, %module के माध्यम से या तो जब आप इसे कॉल करते हैं तो कमांड लाइन से .i फ़ाइल।

एसडब्ल्यूआईजी जेनरेटेड पायथन में आपके लिए डीएलएल की लोडिंग को संभालने के लिए कोड है - इसके साथ सीटीपी या कुछ भी इस्तेमाल करने की आवश्यकता नहीं है। जेनरेट कोड इंटरफ़ेस से मेल खाता है जिसे आपने SWIG से पाइथन में जितना संभव हो सके लपेटने के लिए कहा था और जादुई रूप से कॉल को आपके लिए C++ पक्ष में बंद कर दिया था।

इस प्रकार अगर sdrts_reverse_burst_ff एक नि: शुल्क समारोह है आप कर सकते हैं:

import ModuleName 

ModuleName.sdrts_reverse_burst_ff() 

आप सुनिश्चित करें कि आप नाम बड़ा घूँट के साथ DLL का निर्माण यह की अपेक्षा करता है बनाने की जरूरत है - यह अपवाद से बहुत स्पष्ट हो जाएगा कि पाइथन उठाता है अगर यह मामला नहीं है। आप शायद इसे अपने कार्यान्वयन के खिलाफ भी जोड़ना चाहते हैं जिसमें sdrts_reverse_burst_ff() शामिल है जब तक कि यह शीर्षलेख केवल कार्य न हो।

+0

मैं जेनरेट की गई पायथन फ़ाइल का उपयोग करता हूं, और इसमें एक आयात सहायक है। लेकिन यह _my_dll आयात करते समय विफल रहता है, और यह कहता है: ImportError: _my_dll नामक कोई मॉड्यूल नहीं। मैंने _my_dll को PYTHONPATH और LD_LIBRARY_PATH दोनों के लिए पूर्ण पथ जोड़ा, यह इसे ढूंढने में सक्षम होना चाहिए। – user1165959

+0

@ user1165959 - आपको यह सुनिश्चित करने की ज़रूरत है कि इसे * बिल्कुल * "_my_dll.dll" कहा जाता है, तो यदि पाइथन शिकायत करता है। विंडोज सिस्टम पर मैंने इसे उस बिंदु पर वर्तमान निर्देशिका में डालने का प्रयास किया है जो पाइथन को बुलाया जाता है। किसी भी तरह से ctypes इसे ठीक करने का तरीका नहीं है - आपको पथ + लोडिंग समस्या को ठीक करने की आवश्यकता है और यह सब फिर से काम करेगा। – Flexo

+1

हां, इसे बिल्कुल _my_dll.dll कहा जाता है, और मैंने इसे c: \ Python27 के अंतर्गत डालने का भी प्रयास किया और यह अभी भी इसे नहीं मिला। Ctypes.WinDLL ("_ my_dll.dll") का उपयोग करते समय यह केवल डीएलएल पा सकता है। लेकिन चूंकि आपने उल्लेख किया है कि यह करने का तरीका नहीं है, मुझे लगता है कि मैंने जो डीएल बनाया है उसे SWIG के पहचानने योग्य प्रारूप में संकलित नहीं किया गया था। जिस तरह से मैं स्विग का उपयोग करता हूं वह है: swig -module _my_dll -fvirtual -python -modern -C++ -outdir। -o _my_dll.cxx _my_dll.i और फिर मैंने _my_dll.cxx को एक डीएल में संकलित किया जिसका उपयोग मैं वीसी ++ 2008 एक्सप्रेस संस्करण का उपयोग करके _my_dll.i उत्पन्न करने के लिए करता था। मैंने कुछ भी गलत किया? – user1165959

1

तो अंतिम संक्षिप्त उत्तर यह प्रतीत होता है कि सी ++ बिल्ड को _my_dll.pyd (_my_dll.dll नहीं) का उत्पादन करना चाहिए ताकि विंडोज़ पर पाइथन में my_dll आयात करने में सक्षम हो सके। यह लिनक्स बिल्ड के विपरीत है, जहां कोई _my_dll.so

बस .py फ़ाइल को .dd फ़ाइल का नाम बदल रहा है, लेकिन उपरोक्त टिप्पणियों में बताए गए अनुसार इसे बनाना बेहतर है।

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