2012-01-31 17 views
8

Tôi đọc qua hai chủ đề sau trên wrapping C libraryC++ library, tôi không chắc chắn tôi có được nó chưa. Thư viện C++ mà tôi đang làm việc với không sử dụng class và template, nhưng không theo bất kỳ cách nào phức tạp. Vấn đề là gì hoặc hãy cẩn thận khi gói nó với ctypes (ngoài điểm mà bạn có thể làm như vậy trong python tinh khiết, v.v.)?Đang gói thư viện C++ với ctypes một ý tưởng tồi?

PyCXX, Cython và boost :: python là ba lựa chọn khác mà mọi người đề cập, có sự đồng thuận nào phù hợp với C++ không?

Cảm ơn

Oliver

Trả lời

9

Đối với C++ một thư viện để có thể truy cập từ Python nó phải sử dụng tên xuất khẩu C, mà về cơ bản có nghĩa là một hàm có tên foo sẽ có thể truy cập từ ctypes như foo.

này có thể đạt được chỉ bởi kèm theo giao diện công cộng với export C {}, do đó không cho phép quá tải hàm và các mẫu trong đó (chỉ có giao diện nào của thư viện để được bao bọc là có liên quan, các hoạt động bên không và có thể sử dụng bất kỳ tính năng nào của C++ mà họ thích).

Lý do cho điều này là trình biên dịch C++ sử dụng một cơ chế được gọi là tên mangling để tạo tên duy nhất cho các ký hiệu quá tải hoặc templated. Trong khi ctypes vẫn sẽ tìm thấy một chức năng cung cấp cho bạn biết tên của nó mangled, lược đồ mangling phụ thuộc vào trình biên dịch/linker đang được sử dụng và không có gì bạn có thể dựa vào. Tóm lại: không sử dụng ctypes để bọc các thư viện sử dụng các tính năng C++ trong giao diện công khai của chúng.

Cython có cách tiếp cận khác. Nó hỗ trợ bạn trong việc xây dựng một mô-đun mở rộng C mà giao tiếp với thư viện gốc. Do đó, việc liên kết tới thư viện C++ được thực hiện bởi cơ chế liên kết C++ thông thường, do đó tránh được vấn đề nói trên. Vấn đề với Cython là các thư viện mở rộng C cần phải được biên dịch lại cho mọi nền tảng, nhưng dù sao, điều này cũng áp dụng cho thư viện C++ được gói gọn.

Cá nhân, tôi muốn nói rằng trong hầu hết các trường hợp, thời gian để khởi động Cython là thời gian được chi tiêu tốt và cuối cùng sẽ trả hết so với ctypes (ngoại trừ giao diện Cish đơn giản).

Tôi không có bất kỳ trải nghiệm nào với boost.python, vì vậy tôi không thể nhận xét về nó (tuy nhiên, tôi không có ấn tượng rằng nó rất phổ biến).

+0

Cảm ơn bạn đã đưa Cython lên làm tùy chọn! Tôi đã chọn nó để gói C api và có một trải nghiệm tích cực - nó giống như viết Python với một vài dòng C trong đó, và cho rất nhiều kiểm soát. Một điều tôi đã gặp khó khăn với quá trình xây dựng là đúng - tôi đã kết thúc trước khi biên dịch các tệp Cython trước khi tạo phân phối nguồn. Nếu có ai có vấn đề tương tự, tôi giải thích chi tiết cách tôi gói C api của tôi với Cython ở đây, bao gồm quá trình xây dựng: http://martinsosic.com/development/2016/02/08/wrapping-c-library-as-python -module.html – Martinsos

14

Trong bảo vệ boost::python, được đưa ra câu trả lời của Alexander trên ctypes:

Boost python cung cấp một rất "C++" giao diện giữa C++ và mã python - thậm chí làm những việc như lớp con trăn cho phép của C++ lớp để ghi đè lên các phương pháp ảo tương đối đơn giản. Dưới đây là danh sách các tính năng tốt trong chậu:

  • Cho phép các lớp con C++ ảo bị ghi đè bởi lớp con python.
  • Cầu giữa std::vector<>, std::map<> trường và danh sách python và từ điển (sử dụng vector_indexing_suitemap_indexing_suite)
  • chia sẻ Tự động đếm tham chiếu trong con trỏ thông minh (boost::shared_ptr, vv) với số lượng tài liệu tham khảo trăn (và bạn có thể mở rộng này cho bất kỳ con trỏ thông minh).
  • Kiểm soát quyền sở hữu hạt mịn khi chuyển đối số và trả về giá trị từ các hàm.

Về cơ bản, nếu bạn có thiết kế nơi bạn muốn hiển thị giao diện C++ theo cách trung thành với ngôn ngữ, hãy tăng :: python có lẽ là cách tốt nhất để làm điều đó.

Nhược điểm duy nhất là tăng thời gian biên dịch (tăng :: python sử dụng rộng rãi các mẫu) và đôi khi các thông báo lỗi mờ nếu bạn không nhận được thông tin đúng.

+2

Vấn đề khác là khớp nối mạnh mẽ của các phiên bản tăng cường và python. Ví dụ, nếu bạn nâng cấp phiên bản python của bạn, bạn sẽ phải xây dựng lại phiên bản của boost – user1827356

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