2012-10-23 27 views
8

आयात करने के लिए अनिर्धारित प्रतीक त्रुटि मैं अपने सी ++ कक्षाओं में से एक को पायथन मॉड्यूल के रूप में उपलब्ध करना चाहता हूं। कक्षा को Foo.h हेडर में घोषित किया गया है और एक .cpp Foo.cpp में कार्यान्वित किया गया है। (जी ++ - 4.5, उबंटू x86_64)।साइथन मॉड्यूल

Foo.cpp:

Foo::Foo() : alfa(1.0), beta(1) 
{ 

} 

Foo::~Foo() 
{ 
} 

Foo.h:

setup.py

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

setup(
    name = 'MyDemo', 
    ext_modules=[ 
    Extension("Foo" 
      sources=["Foo.pyx"], 
      include_dirs=[".","../eigen/"], 
      language="c++"), 
    ], 
    cmdclass = {'build_ext': build_ext}, 
) 
0:

class Foo 
{ 
public: 

    Foo() 
    Foo(const Foo& orig); 
    ~Foo(); 
    double alfa; 
    int beta; 
}; 

मैं एक setup.py बनाया के रूप में Cython ट्यूटोरियल में दिखाया गया है यह एक बहुत ही बहुत ही सरल वर्ग है

और cython ट्यूटोरियल के निर्देश का पालन किया मेरी Foo.pyx cython मॉड्यूल लिखने के लिए:

Foo.pyx

cdef extern from "Foo.h": 
    ctypedef struct c_Foo "Foo": 
     double alfa 
    c_Foo *new_Foo "new Foo"() 
    void del_Foo "delete" (c_Foo *myfoo) 

cdef class Foo: 
    cdef c_Foo *thisptr  # hold a C++ instance which we're wrapping 
    def __cinit__(self): 
     self.thisptr = new_Foo() 
    def __dealloc__(self): 
     del_Foo(self.thisptr) 

मैं निम्न आदेश के साथ संकलन: python setup.py build_ext --inplace

running build_ext 
skipping 'Foo.cpp' Cython extension (up-to-date) 
building 'Foo extension 
gcc -pthread -fno-strict-aliasing -DNDEBUG -g -fwrapv -O2 -Wall -Wstrict-prototypes -fPIC -I. -I../eigen/ -I/usr/include/python2.6 -c Foo.cpp -o build/temp.linux-x86_64-2.6/Foo.o 
cc1plus: warning: command line option "-Wstrict-prototypes" is valid for Ada/C/ObjC but not for C++ 
g++ -pthread -shared -Wl,-O1 -Wl,-Bsymbolic-functions build/temp.linux-x86_64-2.6/Foo.o -o /home/linello/prova/Foo.so 

अब Foo.so साझा लाइब्रेरी ऑब्जेक्ट बनाया गया है, लेकिन जब मैं इसे पायथन से आयात करना चाहता हूं, तो मुझे मिलता है:

>>> import Foo 
     Traceback (most recent call last): 
     File "<stdin>", line 1, in <module> 
     ImportError: ./Foo.so: undefined symbol: _ZN4FooD1Ev 
>>> 

मुझे लगता है कि _ZN4FooD1EvFoo के निर्माता के घायल नाम है, लेकिन समझ में नहीं आता कि कैसे प्रतीक याद आ रही है।

मैं वास्तव में समझ नहीं पा रहा हूं कि साझा ऑब्जेक्ट फ़ाइल से कौन सा प्रतीक गुम है। और दूसरे बिंदु के रूप में, python setup.py build_ext --inplace कमांड के बाद, मेरी Foo.cpp फ़ाइल गड़बड़ है और इसमें सिथोनिज्ड संस्करण शामिल है।

किसी अन्य प्रारूप में साइथोनिज्ड फ़ाइल का नाम बदलने के लिए कैसे संभव है (उदाहरण के लिए .cxx) और उस लिंकर त्रुटि से बचें?

मैं तो pFoo.pyx में Foo.pyx संशोधित और फलस्वरूप संशोधित setup.py, अभी सेटअप आदेश के बाद मैं Foo.cxx में pFoo.pyx की cythonized संस्करण है लेकिन जब मैं आयात करने की कोशिश मैं

ImportError: dynamic module does not define init function (initpyFoo)

मिल क्या मेरे सेटअप के साथ गलत है और मेरी समस्याओं को हल करना संभव है?

+0

क्या फू क्लास की प्रतिलिपि कन्स्ट्रक्टर सीपीपी फ़ाइल में परिभाषित है? –

+0

नहीं, वास्तव में कोई कॉपी कन्स्ट्रक्टर परिभाषित नहीं है, जब 'pooFoo.pyx' में 'Foo.pyx'' के नाम को परिभाषित और नामित किया गया है, तो मैंने समस्या हल की। – linello

उत्तर

2

मेरा सुझाव है कि आप अपने साइथन मॉड्यूल के लिए एक अलग नाम का उपयोग करें, उदा।cFoo, नाम टक्कर समस्या से बचने के लिए:

from distutils.core import setup 
from Cython.Build import cythonize 

setup(ext_modules = cythonize(
      "cFoo.pyx",     # our Cython source 
      sources=["Foo.cpp"],  # additional source file(s) 
      language="c++",    # generate C++ code 
    )) 

एक सी ++ वर्ग को परिभाषित करने के लिए, 'cppclass' कीवर्ड, जैसा कि नीचे का उपयोग करें:

cdef extern from "Foo.h": 
    cdef cppclass Foo: 
     Foo() 
     double alfa 
     int beta 

फिर आप इतने की तरह अपने वर्ग का उपयोग करने के लिए सक्षम होना चाहिए :

cdef Foo *foo = new Foo() 
foo.beta = 42