2013-05-28 6 views
8

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

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

मैं स्रोत फ़ाइलों के लिए इस तरह की निर्देशिका संरचना की कल्पना करता हूं, और कुछ साइथन के लिए निर्देशिका बनाता हूं।

Project/ 
    src/ 
     *.h 
     *.cpp 
    cython/ 
     Project.pyx 
     setup.py 
+0

क्या आपकी सी ++ परियोजना पाइथन के बिना उपयोग की जा सकती है? क्या समानांतर ctypes, cffi -based bindings (विभिन्न ट्रेडों के साथ अधिक लक्ष्य का समर्थन करने के लिए) बनाने के लिए यह समझ में आता है जो एक ही पायथन इंटरफ़ेस प्रदान करता है? – jfs

+0

@ जेएफ। सेबेस्टियन परियोजना पाइथन (अब के लिए) के बिना इस्तेमाल और उपयोग की जानी चाहिए। मैं आपका दूसरा प्रश्न नहीं समझता। – clstaudt

+2

फिर तर्कसंगत रूप से आपके पास दो परियोजनाएं हैं: libproject (सी ++ लाइब्रेरी) और पायप्रोजेक्ट (पायथन मॉड्यूल जो पाइथन से libproject का उपयोग करने की अनुमति देता है)। दृढ़ता के लिए (स्रोतों और सह-विकास से स्थापित करना आसान) में आप पाइप्रोजेक्ट के अंदर libproject शामिल हो सकते हैं। दूसरे प्रश्न पर: कई पायथन संस्करणों पर तैनाती के लिए ctypes- आधारित बाइंडिंग आसान हो सकती है। बेहतर पिपी समर्थन के लिए सीएफआई-आधारित बाइंडिंग का उपयोग किया जा सकता है। उदाहरण के लिए, 'pyinotify' दोनों में ctypes- आधारित है और सी में लिखा गया मूल एक्सटेंशन,' pyzmq' में दोनों सीएफआई और साइथन आधारित कार्यान्वयन हैं। चाहे आपको इसकी आवश्यकता हो, आपकी परियोजना पर निर्भर करता है। – jfs

उत्तर

5

मूल रूप से मैं 3 फ़ोल्डर:

  1. CPROJECT, सी ++ पुस्तकालय: एक libcproject.so साझा वस्तु
  2. CYPROJECT, cythonized अजगर विस्तार उत्पादन: cyproject.so Cython
  3. DEPENDENCIES का उपयोग कर उत्पादन, निर्भरता: जहां मैं दोनों परियोजनाओं के लिए बाहरी आवश्यकताओं की प्रतिलिपि बनाता हूं

1. में मैं सी ++ विस्तार का निर्माण (जीसीसी के साथ संकलित - -shared, -fPIC संकलन विकल्प) कि अजगर को और CYPROJECT पायथन के लिए सुविधाओं का पर्दाफाश करने पर निर्भर करता है कि सामने आ जाएगी। पोस्ट प्रोसेसिंग कमांड के रूप में, परिणामस्वरूप .so को DEPENDENCIES/libcproject/ (साथ ही include फ़ाइलों) में कॉपी किया गया है। इस तरह लाइब्रेरी निश्चित रूप से शुद्ध सी ++ प्रोजेक्ट में स्वतंत्र रूप से प्रयोग योग्य है।

  • adapters: जो मुख्य रूप से सी ++ अतिरिक्त कक्षाएं (अक्सर libcproject.so द्वारा प्रदान की लोगों से व्युत्पन्न वर्ग) शामिल

    2. मैं 3 उप फ़ोल्डरों का उपयोग करें। वे आमतौर पर कक्षाएं होती हैं जो साइथन आवश्यकताओं के लिए विशिष्ट कार्यक्षमताओं के साथ बढ़ायी जाती हैं (जैसे सी संस्करण को लक्षित पायथन संस्करण के संग्रहित करना - object से - किसी दिए गए वर्ग और संदर्भ गणना प्रबंधन से Py_XINCREF और Py_DECREF के माध्यम से, ...) ।

  • pyext: .pyx फ़ाइलों को लिखे गए सभी साइथन हाथों को संग्रहीत किया जाता है।
  • setup:। (निर्भरता रास्तों की स्थापना और अंतिम cyproject.so (PYTHONPATH के लिए जोड़ा जा करने के लिए) और cyproject.pyx पैदा करने के लिए python setup.py build_ext --inplace फोन करने के लिए setup.sh स्क्रिप्ट से युक्त

तो क्या setup उप फ़ोल्डर में है ?(मुख्य रूप से प्रदर्शित करने के लिए अतिरिक्त adapters कैसे संकलित किए जाते हैं) setup.py का एक उदाहरण

export PYTHONPATH=$PYTHONPATH:../../../DEPENDENCIES/Cython-0.18 
export PATH=$PATH:../../../DEPENDENCIES/libcproject:../../../DEPENDENCIES/Cython-0.18/bin 

# Note the `../../../DEPENDENCIES/libcproject`... 

CC="gcc" \ 
CXX="g++" \ 
    python setup.py build_ext --inplace 

और यहाँ:

import sys 
import os 
import shutil 

from distutils.core import setup 
from distutils.extension import Extension 
from Cython.Distutils import build_ext 

# Cleaning 
for root, dirs, files in os.walk(".", topdown=False): 
    for name in files: 
     if (name.startswith("cyproject") and not(name.endswith(".pyx"))): 
      os.remove(os.path.join(root, name)) 
    for name in dirs: 
     if (name == "build"): 
      shutil.rmtree(name) 

# Building 
setup(
    cmdclass = {'build_ext': build_ext}, 
    ext_modules = [ 
    Extension("cyproject", 
       sources=["cyproject.pyx", \ 
         "adapter/ALabSimulatorBase.cpp", \ 
         "adapter/ALabSimulatorTime.cpp", \ 
         "adapter/ALabNetBinding.cpp", \ 
         "adapter/AValueArg.cpp", \ 
         "adapter/ALabSiteSetsManager.cpp", \ 
         "adapter/ALabSite.cpp", \ 
         ], 
       libraries=["cproject"], 
       language="c++", 
       extra_compile_args=["-I../inc", "-I../../../DEPENDENCIES/python2.7/inc", "-I../../../DEPENDENCIES/gsl-1.8/include"], 
       extra_link_args=["-L../lib"] 
       extra_compile_args=["-fopenmp", "-O3"], 
       extra_link_args=[] 
      ) 
    ] 
)     

और अंत में, मुख्य .pyx

यहाँ setup.sh के लिए एक नमूना कोड है , जो सिथॉन भाग के साथ .pyx एस लिखा है [cyproject.pyx]:

include "pyext/Utils.pyx" 
include "pyext/TCLAP.pyx" 
include "pyext/LabSimulatorBase.pyx" 
include "pyext/LabBinding.pyx" 
include "pyext/LabSimulatorTime.pyx" 
... 

नोट: सभी Cython द्वारा उत्पन्न फ़ाइलें इस setup फ़ोल्डर में रहता है, ठीक है, हाथ से लिखा सामान (adapters और pyext) से अलग कर के रूप में उम्मीद।

3. एक अलग DEPENDENCIES फ़ोल्डर का उपयोग करने में चीजें अच्छी तरह से अलग (- और उसके निर्भरता - कुछ अन्य वातावरण में मामले में मैं कदम होगा CYPROJECT) रखने के लिए अनुमति देता है।

यह सब आपको एक सिंहावलोकन देने के लिए (एक प्रासंगिक, मुझे आशा है) कि इस तरह के प्रोजेक्ट को व्यवस्थित कैसे किया जा सकता है।

+0

यह एक विशिष्ट उदाहरण है, लेकिन फिर भी एक सहायक है। – clstaudt

+0

लेकिन मैं सोच रहा था कि यह आपकी ज़रूरतों से मेल खाएगा, क्योंकि विशिष्ट भाग यह है कि मैं एक साझा सी ++ लाइब्रेरी (जिसे आप भी चाहते हैं) और एडाप्टर (जिसे आपको जल्द या बाद में चाहिए, मुझे लगता है) का उपयोग करें। –

+0

ठीक है, मैं आपका उदाहरण बताऊंगा क्योंकि मेरी परियोजना बढ़ती है। – clstaudt