2011-11-07 15 views
6

Tôi đang sử dụng Cython (0.15.2) để tạo phần mở rộng cho Python (2.6.5). Tôi đã tạo một tập tin pxd và một tập tin pyx. Đây là nội dung của tệp pyx của tôi:Lỗi biên dịch Cython cho chức năng miễn phí (Không thể chuyển đổi đối số đối tượng Python thành kiểu 'FooBar *')

cimport capifuncs 

cdef class myArray: 
    cdef capifuncs.myArray *_my_array 
    def __cinit__(self, size): 
     self._my_array = capifuncs.array_new(size) 
     if (self._my_array is NULL): 
      raise MemoryError() 

    def __dealloc__(self): 
     if self._my_array is not NULL: 
      capifuncs.array_free(self._my_array) 

    def __bool__(self): 
     return not capifuncs.IsEmpty(self._my_array) 


    ############################## 
    #  Array methods  # 
    ############################## 

    cpdef getItem(self, unsigned int pos): 
     if capifuncs.IsEmpty(self._my_array): 
      raise IndexError("Array is empty") 
     #if(): 
     # raise IndexError("Array bounds exceeded") 

     return capifuncs.array_get_item(self._my_array, pos) 


    cpdef setItem(self, unsigned int pos, double val): 
     if capifuncs.IsEmpty(self._my_array): 
      raise IndexError("Array is empty") 
     #if(): 
     # raise IndexError("Array bounds exceeded") 

     capifuncs.array_set_item(self._my_array, pos, val) 




# Free functions 
cpdef long someCAPIFuncCall(capifuncs.FooBar *fb, capifuncs.myArray *arr, long start, long stop): 
    return capifuncs.doSomethingInteresting(fb, arr, start, stop) 

Nếu tôi nhận xét câu lệnh định nghĩa hàm miễn phí (tức là không phải thành viên), mã biên dịch chính xác và phần mở rộng được tạo. Tuy nhiên, nếu tôi bỏ ghi chú nó và cố gắng để biên dịch các tập tin, tôi nhận được thông báo lỗi sau:

cafuncs.pyx:64:23: Cannot convert Python object argument to type 'FooBar *'

nguyên nhân của việc này là gì, và làm thế nào để sửa chữa nó?

Trả lời

4

Một chức năng định nghĩa là cpdef là callable từ cả Python và C.

Nếu các đối số được khai báo là kiểu dữ liệu C, Cython sẽ cố gắng để tự động chuyển đổi các đối tượng thông qua vào chức năng khi nó được gọi là từ Python. Nhưng các chuyển đổi như vậy chỉ có thể cho các loại số và chuỗi - tất cả các loại khác sẽ dẫn đến lỗi biên dịch.

Ý của bạn là hiển thị hàm này với Python? Nếu không, hãy xác định nó với cdef.

Nếu không, bạn sẽ cần phải tạo trình bao bọc cho các loại C mà bạn muốn chuyển đến và từ Python. Xem Cython Tutorials để biết một số ví dụ về cách thực hiện việc này.

+0

có, tôi muốn có thể gọi hàm C từ Python - lý do để xây dựng tiện ích mở rộng là có thể sử dụng các kiểu dữ liệu và hàm trong thư viện C, từ Python - vì vậy, tôi cần phải có thể gọi hàm C từ Python, và chuyển cho nó các kiểu dữ liệu C (từ Python) –

+0

Một cách hợp lý, nếu tôi sử dụng cdef thay vì cpdef, mã biên dịch, nhưng tôi nhận được thông báo cảnh báo sau: warning: '__pyx_f_6clib_doSomethingInteresting' đã định nghĩa không được sử dụng. Không ngạc nhiên, khi tôi cố gắng sử dụng hàm từ python, tôi nhận được lỗi AttributeError: đối tượng 'module' không có thuộc tính 'doSomethingInteresting' –

+0

@HomunculusReticulli. Xem câu trả lời cập nhật của tôi. Về cơ bản, bạn cần tạo trình bao bọc cho các loại C của mình. – ekhumoro

Các vấn đề liên quan