Vì vậy, sau nhiều lần chọc, thử và sai, la hét và xé tóc ra, cuối cùng tôi cũng đã làm việc này. Đầu tiên, tôi phải viết lại C++ của mình thành C, mà tôi thực sự chỉ chuyển đổi tất cả các biến số std::string
thành char*
và theo dõi một số độ dài.
Sau khi hoàn tất, tôi có các tệp .h và .c. Tôi muốn tạo một hàm duy nhất từ mã C có sẵn bằng Python. Nó chỉ ra rằng Cython có thể biên dịch các tập tin C của bạn vào phần mở rộng cho bạn và liên kết bất kỳ thư viện tất cả trong một đi, vì vậy bắt đầu với thiết lập của tôi.py, nó đã kết thúc tìm kiếm như thế này:
from distutils.core import setup
from distutils.extension import Extension
from Cython.Distutils import build_ext
ext_modules=[
Extension("myext",
["myext.pyx", "../stuff.c"],
libraries=["ssl", "crypto"]
)
]
setup(
name = "myext",
cmdclass = {"build_ext": build_ext},
ext_modules = ext_modules
)
Như bạn có thể thấy, đối số thứ hai đến mở rộng chỉ đơn giản là liệt kê tất cả các tập tin mà cần phải được biên dịch, Cython làm việc ra làm thế nào để biên dịch chúng tùy thuộc vào phần mở rộng tập tin của họ theo như tôi có thể nói. Các mảng thư viện cho trình biên dịch Cython những gì cần phải được liên kết trong (trong trường hợp này tôi đã gói một số công cụ mã hóa mà tôi dường như không thể bắt chước trực tiếp thông qua các thư viện Python hiện có).
Để thực sự làm cho hàm C của tôi khả dụng trong tệp .pyx, bạn viết một trình bao bọc nhỏ trong tệp .pxd. myext.pxd của tôi trông như dưới đây:
cdef extern from "../stuff.h":
char* myfunc(char* arg1, char* arg2, char* arg3)
Trong .pyx sau đó bạn sử dụng tờ khai nhập khẩu cimport chức năng này, mà sau đó có sẵn để sử dụng như thể nó là bất kỳ chức năng Python khác:
cimport myext
def my_python_func(arg1, arg2, arg3):
result = myext.myfunc(arg1, arg2, arg3)
return result
Khi bạn xây dựng này (trên Mac ít nhất) bạn nhận được một .so mà bạn có thể nhập khẩu trong python và chạy các chức năng từ .pyx. Có thể có cách tốt hơn, chính xác hơn để làm cho tất cả điều này hoạt động nhưng điều đó xuất phát từ kinh nghiệm và đây là lần gặp gỡ đầu tiên mà tôi đã cố gắng giải quyết. Tôi sẽ rất quan tâm đến các con trỏ mà tôi có thể đã đi sai.
Cập nhật:
Sau khi tiếp tục sử dụng Cython, tôi thấy đó là siêu đơn giản để tích hợp nó với C++ quá, một khi bạn biết những gì bạn đang làm. Làm cho string
của C++ có sẵn đơn giản như from libcpp.string cimport string
trong pyx/pyd của bạn. Khai báo lớp C++ là dễ dàng tương tự như:
cdef extern from "MyCPPClass.h":
cdef cppclass MyCPPClass:
int foo;
string bar;
Chắc chắn bạn phải về cơ bản redeclare định nghĩa .h của lớp học của bạn trong một định dạng Pythonic, nhưng đó là một giá nhỏ để trả cho việc tiếp cận đã viết chức năng của C++ .
Nếu câu hỏi của bạn đã được trả lời, vui lòng đánh dấu câu hỏi này là đã trả lời. Nếu không, vui lòng chỉ định câu hỏi của bạn một lần nữa. –
@NiklasR Câu trả lời của bạn bao gồm một số lĩnh vực của tôi về sự nhầm lẫn nhưng không giúp tôi có được tất cả các cách. Tôi đã cho bạn một cuộc bỏ phiếu nhưng dự định viết một câu trả lời đầy đủ của các bit khác tôi đã làm việc ra khi tôi có thời gian rảnh rỗi. – Endophage