2017-01-30 13 views
9

में boost_python के लिए C++ - वर्ग को लिंक करना मैं लिनक्स पर थोड़ी देर के लिए पाइथन को फ़ंक्शंस के निर्यात के लिए एक सी ++ - कक्षा के लिए एक रैपर का उपयोग कर रहा हूं। अब मैं इसे विंडोज़ का उपयोग करके अपने सहकर्मियों को उपलब्ध करना चाहता था। हालांकि, मैं साइगविन में इसके लिए एक उपयोगी बूस्ट_पीथॉन डीएल बनाने में विफल रहता हूं। किसी अन्य डीएलएल में एक निर्भर मॉड्यूल को जोड़ने का प्रयास करते समय समस्या उत्पन्न होती है, अगर मैं निर्भर स्रोत को उसी डीएल में संकलित करता हूं तो यह अपेक्षित कार्य करता है।सिग्विन

सेटअप:

moduleB/moduleB.cpp # The boost wrapper code

#include <python2.7/Python.h> 
#include <boost/python.hpp> 
#include <boost/python/suite/indexing/vector_indexing_suite.hpp> 

#include "submodule.hpp" 

using namespace boost::python; 
using namespace testspace; 
using namespace std; 

struct cModuleB : public SubModuleClass { 
    cModuleB(string name, bool boolVar) : SubModuleClass(name,  boolVar) { 
    } 

    void printFunc(string strVar, list listVar, int nIntVar=-1) { 
     vector<int> vecList; 
     for (int l=0; l < len(listVar); l++) { 
      vecList.push_back(extract<int>(listVar[l])); 
     } 
     bool bMoreThanHalf = subModuleFunction(vecList); 
     if (bMoreThanHalf) { 
      cout << "More than half elements are more than 1"; 
     } 
     return; 
    } 
}; 

BOOST_PYTHON_MODULE(moduleB) 
{ 
    class_<cModuleB>("cModuleB", init<std::string, bool>()) 
     .def("printFunc", &cModuleB::printFunc); 
} 

submodule/submodule.hpp # The submodule containing the c++ class

#include <vector> 
#include <string> 

using namespace std; 

namespace testspace { 

    class SubModuleClass { 

    public: 
      SubModuleClass(string name = "", bool bIsGreat = false); 
      ~SubModuleClass(); 

      bool subModuleFunction(vector<int> & myVec); 
    }; 
} 
  • submodule/submodule.cpp # The c++ class definition
using namespace std; 

#include "submodule.hpp" 

using namespace testspace; 

SubModuleClass::SubModuleClass(string name, bool bIsGreat) 
{  
} 

SubModuleClass::~SubModuleClass() 
{    
} 

bool SubModuleClass::subModuleFunction(vector<int> & myVec) 
{ 
    int nCounter = 0; 
    for (vector<int>::iterator vi = myVec.begin(); vi != myVec.end(); vi++) { 
     if (*vi > 1) nCounter++; 
    } 
    if (nCounter*2 > (int)myVec.size()) { 
     return true; 
    } 
    else { 
     return false; 
    } 
} 

देवदार

मैं एक समस्या प्रदर्शित एक न्यूनतम उदाहरण बनाया है सेंट हम निम्नलिखित दो आदेशों द्वारा किसी साझा लाइब्रेरी में submodule संकलन:

g++ -MMD -MP -ffloat-store -m64 -O0 -ggdb -DDEBUG -D_DEBUG \ 
    -c submodule/submodule.cpp -o submodule/submodule.o 

g++ -m64 -shared -Wl,-soname=cygsubmodule_for_moduleB.dll \ 
    -Wl,--whole-archive submodule/submodule.o -Wl,--no-whole-archive \ 
    -Wl,--out-implib,./libsubmodule_for_moduleB.dll.a \ 
    -Wl,--export-all-symbols -Wl,--enable-auto-import \ 
    -o submodule/cygsubmodule.dll 

और हम वास्तविक आवरण कोड संकलन और एक boost_python dll कि हम अजगर से आयात करने में सक्षम होना चाहिए में लिंक (सत्यापित है कि शामिल उदाहरण उबंटू पर मिलते हैं)।

g++ -MMD -MP -ffloat-store -m64 -O0 -ggdb -fPIC \ 
    -Isubmodule -I/usr/include/python2.7 -DDEBUG -D_DEBUG \ 
    -c moduleB/moduleB.cpp -o moduleB/moduleB.o 

g++ -m64 -shared -Wl,-soname=cygmoduleB.dll \ 
    -Wl,--whole-archive moduleB/moduleB.o -Wl,--no-whole-archive \ 
    -Wl,--out-implib,./libmoduleB.dll.a -Wl,--export-all-symbols \ 
    -Wl,--enable-auto-import -Lsubmodule -lsubmodule -lstdc++ 
    -lboost_python -lpython2.7 -o moduleB/cygmoduleB.dll 

ubuntu में इस मॉड्यूल .so फ़ाइल से cyg -prefix को दूर करने और यह सुनिश्चित करें कि submodule.soLD_LIBRARY_PATH में होने की पुष्टि करने के बाद के रूप में इस्तेमाल किया जा सकता।

>>> import moduleB 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
ImportError: No such file or directory 

cygwin और Ubuntu एक के बीच काम कर रहे moduleB पर ldd के मतभेद की जांच देख सकते हैं कि बढ़ावा और अजगर DLLs moduleB.dll से उत्पादन में प्रश्न चिह्न द्वारा प्रतिस्थापित beeen है: हालांकि, cygwin क्लासिक आयात त्रुटि दिखाता है। cygwin पर

moduleB: Ubuntu पर

# ldd moduleB.dll 
ntdll.dll => /cygdrive/c/Windows/SYSTEM32/ntdll.dll (0x778b0000) 
kernel32.dll => /cygdrive/c/Windows/system32/kernel32.dll (0x77470000) 
KERNELBASE.dll => /cygdrive/c/Windows/system32/KERNELBASE.dll (0x7fefdfd0000) 
SYSFER.DLL => /cygdrive/c/Windows/System32/SYSFER.DLL (0x75090000) 
??? => ??? (0x4f3d00000) 

moduleB:

# ldd moduleB.so 
linux-vdso.so.1 => (0x00007fff55b73000) 
libsubmodule.so => libsubmodule.so (0x00007fee4f9d7000) 
libstdc++.so.6 => /usr/lib/x86_64-linux-gnu/libstdc++.so.6 (0x00007fee4f6a8000) 
libpython2.7.so.1.0 => /usr/lib/x86_64-linux-gnu/libpython2.7.so.1.0 (0x00007fee4f144000) 
libboost_python-py27.so.1.55.0 => /usr/lib/x86_64-linux-gnu/libboost_python-py27.so.1.55.0 (0x00007fee4eef7000) 
libgcc_s.so.1 => /lib/x86_64-linux-gnu/libgcc_s.so.1 (0x00007fee4ece1000) 
libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007fee4e91b000) 
libm.so.6 => /lib/x86_64-linux-gnu/libm.so.6 (0x00007fee4ddbf000) 
/lib64/ld-linux-x86-64.so.2 (0x000055f47c1a6000) 
libpthread.so.0 => /lib/x86_64-linux-gnu/libpthread.so.0 (0x00007fee4dba0000) 
libz.so.1 => /lib/x86_64-linux-gnu/libz.so.1 (0x00007fee4d987000) 
libdl.so.2 => /lib/x86_64-linux-gnu/libdl.so.2 (0x00007fee4d783000) 
libutil.so.1 => /lib/x86_64-linux-gnu/libutil.so.1 (0x00007fee4d580000) 

क्यों moduleB cygwin में एक boost_module के रूप में खुद की पहचान करने में विफल रहता है, और के रूप में किसी भी विचार क्यों g++ उचित शामिल करने के लिए विफल रहता है निर्भरता की जानकारी?

boost_python साइगविन में पैकेज का उपयोग करके स्थापित किया गया था।


अद्यतन: सही उत्तर नीचे, दो बातें ध्यान दिया जाना चाहिए कि सही समाधान समझ से परे के अलावा:

  1. ldd cygwin पर पर ubuntu रूप में एक ही उत्पादन नहीं देता है और <library>.dll => not found के बजाय यह केवल ? => ? (<address>)
  2. कुछ प्रदर्शित करता है जब boost मॉड्यूल को साइगविन पर पाइथन में लोड करते समय 01 पर निर्भर करता हैपथ में नहीं, हमें एक संदेश नहीं मिलता है कि एक डीएल गुम है, केवल बूस्ट मॉड्यूल नहीं मिल सकता है।
+0

जी ++, अवधि के साथ लिंक सी ++ मॉड्यूल। जीसीसी ने कहा या कुछ और काम करना चाहिए? वैसे भी, अपने वास्तविक निर्माण आदेशों को दिखाकर आमंत्रित करें। –

+0

@ एनएम। मैंने एक पूर्ण कार्य उदाहरण के साथ पोस्ट को अद्यतन किया है। – fnokke

+0

आप मॉड्यूल का नाम और फ़ाइल नाम के बीच एक बेमेल है। आप cyfmoduleB.dll बनाते हैं लेकिन इसे moduleB.dll कहा जाना चाहिए। मैंने आपके चरणों को दोबारा बनाया है, cygmoduleB.dll को moduleB.dll में बदल दिया है, और परिणाम एक मॉड्यूल है जो पाइथन (gcc 5.4.0, cygwin आज अपडेट किया गया) के साथ पूरी तरह से अच्छी तरह से काम करता है। –

उत्तर

1

निम्न परिवर्तन किए जाने चाहिए:

  1. लिंक सी ++ कार्यक्रमों और पुस्तकालयों g++ साथ।
  2. पायथन मॉड्यूल नाम फ़ाइल नाम से मेल खाना चाहिए, इसलिए यदि फ़ाइल का नाम moduleB.dll है तो वहां एक पंक्ति होनी चाहिए जो कहीं कहीं BOOST_PYTHON_MODULE(moduleB) कहती है।
  3. आदेश वास्तव में मॉड्यूल लोड करने के लिए में, यह पायथन के sys.path में होना चाहिए, और अपने सभी निर्भरता खिड़कियों %PATH% (या मौजूदा निर्देशिका में, या जहाँ भी विंडोज निर्भर DLLs डाल करने के लिए अनुमति देता है) में होना चाहिए। LD_LIBRARY_PATH सिगविन में काम नहीं करता है जिस तरह से यह वास्तविक यूनिक्स सिस्टम में काम करता है।
संबंधित मुद्दे