2012-07-28 30 views
19

Tôi đã tìm thấy câu trả lời một phần giữa các tài liệu, danh sách gửi thư, và this question here, nhưng tôi muốn để có được một câu trả lời trực tiếp hơn việc giải quyết chi tiết cụ thể của tôi ...cấu trúc dự án cho gói nhiều C++ lớp trong cython đến một đối tượng chia sẻ duy nhất

Tôi đang học cython bằng cách cố gắng để bọc các phần nhỏ, từng chút một, của một thư viện mà tôi đã sử dụng mà hiện đang được bọc trong tăng :: python. Tôi đã đóng góp một chút nhỏ cho wrapper tăng này, và đang sử dụng nó như là một tài liệu tham khảo C++, trong khi cùng lúc tôi đang sử dụng ZeroMQ Python bindings như một tham chiếu cython.

Câu hỏi của tôi là về cấu trúc dự án. Phiên bản tăng cường hiện tại của lib này biên dịch thành một đơn .so và đó là mục tiêu của tôi. Tôi nhanh chóng phát hiện ra rằng bạn không thể trực tiếp biên dịch nhiều mô-đun .pyx thành một đơn .so. Sau đó tôi bắt đầu đi xuống con đường xác định các tệp cppclass trong các tệp pxd và các tệp triển khai trùn tương ứng của chúng trong .pxi và cố gắng đưa chúng vào một đơn pyx để biên dịch. Trong khi nó làm việc lúc đầu, một khi tôi đã viết nhiều hơn một chút tôi nhấn vấn đề với nhiều định nghĩa xung đột vì pxi bao gồm ở những nơi khác nhau.

Tôi rất thích nghe một cách tiếp cận tổ chức phù hợp nhằm giải quyết các câu hỏi sau và mục tiêu:

  • Đặt tên lớp công chúng giống như cppclass (Tôi đang làm điều này bây giờ bằng cách có cppclass trong một khác nhau tên pyd và sử dụng không gian tên nhập khẩu để xử lý những cái tên tương tự, ala Using cimport to resolve naming conflicts)
  • Độc .so như sản lượng biên dịch (acceptable approach?)
  • tôi sử dụng pyx đa bao gồm cách tiếp cận vào chính pyx cho rằng một mình, hoặc nên pyx chính có chứa bất cứ điều gì khác ngoài chỉ giữ các bao gồm?
  • Nơi xác định trung tâm các hằng số sẽ được xuất trong python?
  • Có cấu trúc thư mục ưa thích nào không? Ngay bây giờ tôi có mọi thứ trong một thư mục src lớn bên dưới setup.py của tôi. Thật khó hiểu khi thấy rất nhiều tập tin pxi, pxd, pyx.
  • Hiện tại pxi có hoàn toàn không cần thiết không? Nếu không, tôi có cần phải sử dụng một bảo vệ ifndef kiểu cython để xử lý nhiều tạp giữa các mô-đun khác nhau không?
  • Tôi biết các ràng buộc python ZeroMQ xây dựng nhiều mô-đun và sử dụng cách tiếp cận gói bằng cách bao gồm chúng thông qua __init__.py. Đó có thực sự là cách tiếp cận phù hợp với cython không?

Để tham khảo, dự án tôi đang thực hành để bọc lại là PyOpenNI (openni). Mô hình mà dự án tăng này lấy là thu thập các đối tượng chung ở một nơi và sau đó xác định định nghĩa đầu trang 1 đến 1 với nguồn và sau đó có một trình bao bọc lớn thu thập tất cả các định nghĩa vào một vị trí duy nhất. Và cũng có thể xử lý ngoại lệ tùy chỉnh và tiện ích.

Trả lời

20

Trong khi chờ đợi câu trả lời cuối cùng, tôi tiếp tục chơi xung quanh với việc tổ chức mã của mình. Bao gồm các tệp pyx thành một pyx để biên dịch đã hoạt động cho đến nay.

My setup.py là đơn giản như:

ext_modules = [ 
    Extension(
     "openni", 
     ["src/openni.pyx"], 
     language="c++", 
     include_dirs=['src/', '/usr/include/ni'], 
     libraries=['OpenNI'], 
    ) 
], 

Các chính openni.pyx trông giống như:

include "constants.pyx" 
include "exceptions.pyx" 
include "context.pyx" 
... 

tôi có chung một libopenni.pxd để cung cấp tuyên bố chỉ externs với phần còn lại của các mô-đun.

Tôi tên cppclass tờ khai của tôi một pxd tên khác với định nghĩa lớp pyx để tránh va chạm tên:

xncontext.pxd

cdef extern from "XnCppWrapper.h" namespace "xn": 
    cdef cppclass Context: 
      ... 

context.pyx:

from libopenni cimport * 
from xncontext cimport Context as c_Context 

cdef class Context: 
    cdef c_Context *handle 
     ... 
+0

Bạn có thể trỏ đến phần còn lại của mã mà bạn đã đặt cùng nhau cho trình bao bọc này không? Tôi đang chạy vào một vấn đề tương tự với độ phân giải tương tự. Nó không đẹp nhưng nó hoạt động. – ibell

+2

Xin chào. Vì vậy, đây không phải là bất cứ điều gì mà kết thúc trong một repo công cộng. Hầu hết các ví dụ mới nhất của tôi về cấu trúc này không trực tuyến nhưng đây là ví dụ mà tôi đã thực hiện ngay sau này: https: //github.com/chadmv/plow/tree/master/lib/python/src – jdi

+2

Những gì tôi làm bây giờ là giữ các tệp pxi trong và bao gồm thư mục con để làm cho nó sạch sẽ. Và tôi chỉ có pyx đơn chính phía trên nó cùng với pxd chứa tất cả các khai báo bên ngoài để ràng buộc với C/CPP – jdi

0

Answeri ng Có cấu trúc thư mục ưa thích nào không?

Vâng, cấu trúc thư mục ưa thích dành cho Cython của .pyx.pxd file là đối xử với họ một cách chính xác như bạn sẽ .py của bạn tập tin: một cho mỗi mô-đun, trong một cấu trúc gói tổ chức tốt. __init__.pxd tệp có thể được cung cấp giống như các tệp __init__.py để tập hợp một tập hợp các biểu tượng được sắp xếp để thu thập tập hợp các biểu tượng được sắp xếp từ các mô-đun/gói con của nó để nhập dữ liệu.

Đúng, điều này tạo ra một tệp .so cho mỗi mô-đun, nhưng những tệp này bị ẩn trong thư mục xây dựng. Điều này cũng đúng với các mô đun dựng sẵn của Python; có một tệp tương ứng .so cho từng tệp. Đây co phải vân đê?

+0

Gần đây tôi đã chuyển đổi sang phương thức tiếp cận đa và nhập chúng vào một vùng tên duy nhất thông qua __init__. py – jdi

+0

Tôi không biết rằng __init __. pxd có ý nghĩa ở cấp mô-đun – jdi

+0

Các tệp .so riêng biệt cho mọi mô-đun có thể là vấn đề nếu bạn áp dụng cấp phép (bảo vệ) cho các tệp .so đó khi cấp phép mất một chút thời gian để khởi tạo . –

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