Bạn có phải là nhà phát triển Python có thư viện C hoặc C++ mà bạn muốn sử dụng từ Python không? . Xuyên suốt hướng dẫn này, bạn sẽ thấy tổng quan về một số công cụ bạn có thể sử dụng để tạo các liên kết Python
Trong hướng dẫn này, bạn sẽ tìm hiểu về
Hướng dẫn này dành cho các nhà phát triển Python trung cấp. Nó giả định kiến thức cơ bản về Python và một số hiểu biết về các hàm và kiểu dữ liệu trong C hoặc C++. Bạn có thể lấy tất cả mã ví dụ mà bạn sẽ thấy trong hướng dẫn này bằng cách nhấp vào liên kết bên dưới Nhận mã mẫu. Nhấp vào đây để lấy mã mẫu mà bạn sẽ sử dụng để tìm hiểu về Python Bindings trong hướng dẫn này Hãy đi sâu vào xem xét các ràng buộc Python Tổng quan về ràng buộc PythonTrước khi bạn tìm hiểu cách gọi C từ Python, bạn nên dành chút thời gian tìm hiểu lý do tại sao. Có một số tình huống tạo các liên kết Python để gọi thư viện C là một ý tưởng tuyệt vời
Tất cả những điều trên là những lý do tuyệt vời để học cách tạo các liên kết Python để giao tiếp với thư viện C của bạn Ghi chú. Xuyên suốt hướng dẫn này, bạn sẽ tạo các ràng buộc Python cho cả C và C++. Hầu hết các khái niệm chung áp dụng cho cả hai ngôn ngữ và vì vậy C sẽ được sử dụng trừ khi có sự khác biệt cụ thể giữa hai ngôn ngữ. Nói chung, mỗi công cụ sẽ hỗ trợ C hoặc C++, nhưng không hỗ trợ cả hai Bắt đầu nào Loại bỏ các quảng cáoLoại dữ liệu MarshallingChờ đợi. Trước khi bạn bắt đầu viết các liên kết Python, hãy xem cách Python và C lưu trữ dữ liệu và loại sự cố nào sẽ gây ra. Đầu tiên, hãy định nghĩa soái ca. Khái niệm này được Wikipedia định nghĩa như sau
Đối với mục đích của bạn, sắp xếp thứ tự là những gì các liên kết Python đang thực hiện khi chúng chuẩn bị dữ liệu để chuyển dữ liệu đó từ Python sang C hoặc ngược lại. Các ràng buộc Python cần thực hiện sắp xếp lại vì Python và C lưu trữ dữ liệu theo những cách khác nhau. C lưu trữ dữ liệu ở dạng nhỏ gọn nhất trong bộ nhớ có thể. Nếu bạn sử dụng 7, thì nó sẽ chỉ sử dụng tổng cộng 8 bit bộ nhớMặt khác, trong Python, mọi thứ đều là một đối tượng. Điều này có nghĩa là mỗi số nguyên sử dụng một số byte trong bộ nhớ. Có bao nhiêu tùy thuộc vào phiên bản Python bạn đang chạy, hệ điều hành của bạn và các yếu tố khác. Điều này có nghĩa là các ràng buộc Python của bạn sẽ cần chuyển đổi số nguyên C thành số nguyên Python cho mỗi số nguyên được truyền qua ranh giới Các loại dữ liệu khác có mối quan hệ tương tự giữa hai ngôn ngữ. Hãy lần lượt xem xét từng
Bên cạnh việc chuyển đổi loại dữ liệu, có những vấn đề khác mà bạn cần phải suy nghĩ khi xây dựng các liên kết Python của mình. Hãy tiếp tục khám phá chúng Hiểu các giá trị có thể thay đổi và bất biếnNgoài tất cả các loại dữ liệu này, bạn cũng sẽ phải biết cách các đối tượng Python có thể thay đổi hoặc không thay đổi. C có một khái niệm tương tự với các tham số chức năng khi nói về truyền theo giá trị hoặc truyền theo tham chiếu. Trong C, tất cả các tham số đều là giá trị truyền qua. Nếu bạn muốn cho phép một hàm thay đổi một biến trong trình gọi, thì bạn cần chuyển một con trỏ tới biến đó Bạn có thể tự hỏi liệu bạn có thể khắc phục hạn chế bất biến bằng cách chuyển một đối tượng bất biến sang C bằng cách sử dụng một con trỏ hay không. Trừ khi bạn đi đến những điểm cực đoan xấu xí và không di động, Python sẽ không cung cấp cho bạn một con trỏ tới một đối tượng, vì vậy điều này không hoạt động. Nếu bạn muốn sửa đổi một đối tượng Python trong C, thì bạn sẽ cần thực hiện thêm các bước để đạt được điều này. Các bước này sẽ phụ thuộc vào công cụ bạn sử dụng, như bạn sẽ thấy bên dưới Vì vậy, bạn có thể thêm tính bất biến vào danh sách kiểm tra các mục cần xem xét khi tạo các ràng buộc Python. Điểm dừng cuối cùng của bạn trong hành trình tạo danh sách kiểm tra này là cách xử lý các cách khác nhau mà Python và C xử lý với việc quản lý bộ nhớ Quản lý bộ nhớC và Python quản lý bộ nhớ khác nhau. Trong C, nhà phát triển phải quản lý tất cả các phân bổ bộ nhớ và đảm bảo chúng được giải phóng một lần và chỉ một lần. Python sẽ giải quyết vấn đề này cho bạn bằng cách sử dụng trình thu gom rác Mặc dù mỗi cách tiếp cận này đều có những ưu điểm của nó, nhưng nó lại tạo thêm một vấn đề khó khăn trong việc tạo các ràng buộc Python. Bạn sẽ cần biết vị trí bộ nhớ cho từng đối tượng được phân bổ và đảm bảo rằng bộ nhớ chỉ được giải phóng ở cùng một phía của rào cản ngôn ngữ Ví dụ: một đối tượng Python được tạo khi bạn đặt 0. Bộ nhớ cho điều này được phân bổ ở phía Python và cần được thu gom rác. May mắn thay, với các đối tượng Python, thật khó để làm bất cứ điều gì khác. Hãy xem điều ngược lại trong C, nơi bạn cấp phát trực tiếp một khối bộ nhớ
Khi bạn làm điều này, bạn cần đảm bảo rằng con trỏ này được giải phóng trong C. Điều này có thể có nghĩa là thêm mã theo cách thủ công vào các liên kết Python của bạn để thực hiện việc này Điều đó làm tròn danh sách kiểm tra của bạn về các chủ đề chung. Hãy bắt đầu thiết lập hệ thống của bạn để bạn có thể viết một số mã Thiết lập môi trường của bạnĐối với hướng dẫn này, bạn sẽ sử dụng các thư viện C và C++ có sẵn từ repo Real Python GitHub để hiển thị bản kiểm tra của từng công cụ. Mục đích là bạn sẽ có thể sử dụng những ý tưởng này cho bất kỳ thư viện C nào. Để làm theo cùng với tất cả các ví dụ ở đây, bạn sẽ cần phải có những điều sau đây
Cái cuối cùng có thể là mới đối với bạn, vì vậy hãy xem xét kỹ hơn về nó Loại bỏ các quảng cáoSử dụng Công cụ // cmult.c float cmult(int int_param, float float_param) { float return_value = int_param * float_param; printf(" In cmult : int: %d float %.1f returning %.1f\n", int_param, float_param, return_value); return return_value; } 3 3 là công cụ bạn sẽ sử dụng để xây dựng và kiểm tra các liên kết Python của mình trong hướng dẫn này. Nó có mục đích tương tự như 6 nhưng sử dụng Python thay vì Makefiles. Bạn sẽ cần cài đặt 3 trong môi trường ảo của mình bằng cách sử dụng 8 3Để chạy nó, bạn gõ 3 theo sau là nhiệm vụ bạn muốn thực hiện 5Để xem nhiệm vụ nào khả dụng, bạn sử dụng tùy chọn 60
Lưu ý rằng khi bạn xem tệp 61 nơi các tác vụ 3 được xác định, bạn sẽ thấy tên của tác vụ thứ hai được liệt kê là 63. Tuy nhiên, đầu ra từ 60 cho thấy nó là 65. Dấu trừ ( 66) không thể được sử dụng như một phần của tên Python, vì vậy tệp sử dụng dấu gạch dưới ( 67) để thay thếĐối với mỗi công cụ bạn sẽ kiểm tra, sẽ có một nhiệm vụ 68 và một nhiệm vụ 69 được xác định. Ví dụ: để chạy mã cho 70, bạn có thể nhập 71. Một ngoại lệ là 72, vì không có giai đoạn xây dựng nào cho 72. Ngoài ra, có hai nhiệm vụ đặc biệt được thêm vào để thuận tiện
Bây giờ bạn đã có cảm giác về cách chạy mã, hãy xem qua mã C mà bạn sẽ gói gọn trước khi nhấn vào phần tổng quan về công cụ Nguồn C hoặc C++Trong mỗi phần ví dụ bên dưới, bạn sẽ tạo các liên kết Python cho cùng một chức năng trong C hoặc C++. Các phần này nhằm mục đích cung cấp cho bạn cảm nhận về giao diện của từng phương thức, thay vì hướng dẫn chuyên sâu về công cụ đó, vì vậy chức năng bạn sẽ gói gọn là nhỏ. Hàm mà bạn sẽ tạo các ràng buộc Python để lấy một 76 và một 77 làm tham số đầu vào và trả về một 77 là tích của hai số
Các hàm C và C++ gần như giống hệt nhau, với tên nhỏ và chuỗi khác biệt giữa chúng. Bạn có thể lấy một bản sao của tất cả mã bằng cách nhấp vào liên kết bên dưới Nhận mã mẫu. Nhấp vào đây để lấy mã mẫu mà bạn sẽ sử dụng để tìm hiểu về Python Bindings trong hướng dẫn này Bây giờ bạn đã nhân bản repo và các công cụ của bạn đã được cài đặt, bạn có thể xây dựng và kiểm tra các công cụ. Vì vậy, hãy đi sâu vào từng phần bên dưới $ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 72Bạn sẽ bắt đầu với 72, một công cụ trong thư viện chuẩn để tạo các liên kết Python. Nó cung cấp bộ công cụ cấp thấp để tải các thư viện dùng chung và sắp xếp dữ liệu giữa Python và CNó được cài đặt như thế nàoMột trong những lợi thế lớn của 72 là nó là một phần của thư viện chuẩn Python. Nó đã được thêm vào Python phiên bản 2. 5, vì vậy rất có thể bạn đã có nó. Bạn có thể 02 giống như bạn làm với các mô-đun 03 hoặc 04Loại bỏ các quảng cáoGọi hàmTất cả mã để tải thư viện C của bạn và gọi hàm sẽ có trong chương trình Python của bạn. Điều này thật tuyệt vì không có bước bổ sung nào trong quy trình của bạn. Bạn chỉ cần chạy chương trình của mình và mọi thứ đã được lo liệu. Để tạo các ràng buộc Python của bạn trong 72, bạn cần thực hiện các bước sau
Bạn sẽ lần lượt xem xét từng vấn đề này Đang tải thư viện 72 cung cấp một số cách để bạn tải thư viện dùng chung, một số cách dành riêng cho nền tảng. Ví dụ của bạn, bạn sẽ tạo một đối tượng 08 trực tiếp bằng cách chuyển vào đường dẫn đầy đủ đến thư viện dùng chung mà bạn muốn 6Điều này sẽ hoạt động đối với các trường hợp khi thư viện dùng chung nằm trong cùng thư mục với tập lệnh Python của bạn, nhưng hãy cẩn thận khi bạn cố tải các thư viện từ các gói khác với các liên kết Python của bạn. Có nhiều chi tiết để tải thư viện và tìm đường dẫn trong tài liệu 72 dành cho nền tảng và tình huống cụ thểGHI CHÚ. Nhiều sự cố dành riêng cho nền tảng có thể phát sinh trong quá trình tải thư viện. Tốt nhất là thực hiện các thay đổi gia tăng sau khi bạn có một ví dụ hoạt động Bây giờ bạn đã tải thư viện vào Python, bạn có thể thử gọi nó Gọi chức năng của bạnHãy nhớ rằng nguyên mẫu hàm cho hàm C của bạn như sau 7Bạn cần chuyển vào một số nguyên và một số float và có thể mong đợi nhận được một số float được trả về. Số nguyên và số float có hỗ trợ riêng trong cả Python và C, vì vậy bạn mong đợi trường hợp này sẽ hoạt động với các giá trị hợp lý Khi bạn đã tải thư viện vào các liên kết Python của mình, hàm sẽ là một thuộc tính của 00, là đối tượng 01 mà bạn đã tạo trước đó. Bạn có thể thử gọi nó như thế này 0Ối. Điều này không hoạt động. Dòng này được nhận xét trong ví dụ repo vì nó không thành công. Nếu bạn cố chạy với lệnh gọi đó, thì Python sẽ báo lỗi 0Có vẻ như bạn cần thông báo cho 72 về bất kỳ tham số nào không phải là số nguyên. 72 không có bất kỳ kiến thức nào về chức năng trừ khi bạn nói rõ ràng. Bất kỳ tham số nào không được đánh dấu khác được coi là số nguyên. 72 không biết cách chuyển đổi giá trị 05 được lưu trữ trong 06 thành số nguyên nên không thành côngĐể khắc phục điều này, bạn cần tạo một 07 từ số. Bạn có thể làm điều đó trong dòng mà bạn đang gọi hàm 0Bây giờ, khi bạn chạy mã này, nó sẽ trả về tích của hai số bạn đã nhập 30Đợi một chút… 08 nhân với 05 không phải là 00Hóa ra, giống như các tham số đầu vào, 72 giả sử hàm của bạn trả về một giá trị 76. Trên thực tế, hàm của bạn trả về một 77, đang được sắp xếp không chính xác. Cũng giống như tham số đầu vào, bạn cần yêu cầu 72 sử dụng một loại khác. Cú pháp ở đây hơi khác một chút 31Điều đó sẽ làm các trick. Hãy chạy toàn bộ mục tiêu 05 và xem những gì bạn có. Hãy nhớ rằng, phần đầu tiên của đầu ra là trước khi bạn sửa 06 của hàm thành float 32Cái đó tốt hơn. Trong khi phiên bản đầu tiên, chưa được chỉnh sửa trả về giá trị sai, phiên bản cố định của bạn phù hợp với hàm C. Cả C và Python đều nhận được kết quả giống nhau. Bây giờ nó đang hoạt động, hãy xem lý do tại sao bạn có thể muốn hoặc không muốn sử dụng 72Loại bỏ các quảng cáoĐiểm mạnh và điểm yếuƯu điểm lớn nhất của 72 so với các công cụ khác mà bạn sẽ kiểm tra ở đây là nó được tích hợp vào thư viện tiêu chuẩn. Nó cũng không yêu cầu thêm bước nào, vì tất cả công việc được thực hiện như một phần của chương trình Python của bạnNgoài ra, các khái niệm được sử dụng ở mức độ thấp, giúp cho các bài tập như bài bạn vừa làm có thể quản lý được. Tuy nhiên, các tác vụ phức tạp hơn trở nên cồng kềnh do thiếu tự động hóa. Trong phần tiếp theo, bạn sẽ thấy một công cụ bổ sung một số quy trình tự động hóa $ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 70 70 là Giao diện hàm ngoại C cho Python. Cần một cách tiếp cận tự động hơn để tạo các liên kết Python. 70 có nhiều cách để bạn có thể xây dựng và sử dụng các liên kết Python của mình. Có hai tùy chọn khác nhau để chọn, cung cấp cho bạn bốn chế độ có thể
Đối với ví dụ này, bạn sẽ sử dụng chế độ ngoại tuyến API, chế độ này tạo ra mã nhanh nhất và nói chung, trông giống với các liên kết Python khác mà bạn sẽ tạo sau trong hướng dẫn này Nó được cài đặt như thế nàoVì 70 không phải là một phần của thư viện chuẩn nên bạn sẽ cần cài đặt nó trên máy của mình. Bạn nên tạo một môi trường ảo cho việc này. May mắn thay, 70 cài đặt với 8 33Điều này sẽ cài đặt gói vào môi trường ảo của bạn. Nếu bạn đã cài đặt từ 305, thì điều này nên được quan tâm. Bạn có thể xem 305 bằng cách truy cập repo tại liên kết bên dướiNhận mã mẫu. Nhấp vào đây để lấy mã mẫu mà bạn sẽ sử dụng để tìm hiểu về Python Bindings trong hướng dẫn này Bây giờ bạn đã cài đặt 70, đã đến lúc sử dụng nóGọi hàmKhông giống như 72, với 70 bạn đang tạo một mô-đun Python đầy đủ. Bạn sẽ có thể 02 mô-đun giống như bất kỳ mô-đun nào khác trong thư viện tiêu chuẩn. Có một số công việc bổ sung mà bạn sẽ phải làm để xây dựng mô-đun Python của mình. Để sử dụng các ràng buộc 70 Python của bạn, bạn cần thực hiện các bước sau
Điều đó có vẻ tốn nhiều công sức, nhưng bạn sẽ thực hiện từng bước này và xem nó hoạt động như thế nào Viết các ràng buộc 70 cung cấp các phương thức đọc tệp tiêu đề C để thực hiện hầu hết công việc khi tạo các liên kết Python. Trong tài liệu về 70, mã để thực hiện việc này được đặt trong một tệp Python riêng. Đối với ví dụ này, bạn sẽ đặt mã đó trực tiếp vào công cụ xây dựng 3, công cụ này sử dụng các tệp Python làm đầu vào. Để sử dụng 70, bạn bắt đầu bằng cách tạo một đối tượng 316, đối tượng này cung cấp ba phương thức bạn cần 34Khi bạn có FFI, bạn sẽ sử dụng 317 để tự động xử lý nội dung của tệp tiêu đề. Điều này tạo ra các hàm bao bọc để bạn sắp xếp dữ liệu từ Python 35Đọc và xử lý tệp tiêu đề là bước đầu tiên. Sau đó, bạn cần sử dụng 318 để mô tả tệp nguồn mà 70 sẽ tạo 36Đây là bảng phân tích các tham số bạn đang truyền vào
Xây dựng các ràng buộc PythonGọi 318 không xây dựng các liên kết Python. Nó chỉ thiết lập siêu dữ liệu để mô tả những gì sẽ được tạo. Để xây dựng các ràng buộc Python, bạn cần gọi ____1333 37Điều này kết thúc mọi thứ bằng cách tạo tệp 322, tệp 323 và thư viện dùng chung. Tác vụ 3 mà bạn vừa thực hiện có thể được chạy trên dòng lệnh để xây dựng các liên kết Python 38Bạn có các liên kết Python 70 của mình, vì vậy đã đến lúc chạy mã nàyGọi chức năng của bạnSau tất cả công việc bạn đã thực hiện để định cấu hình và chạy trình biên dịch 70, việc sử dụng các liên kết Python đã tạo trông giống như sử dụng bất kỳ mô-đun Python nào khác 39Bạn nhập mô-đun mới và sau đó bạn có thể gọi trực tiếp cho 339. Để kiểm tra, hãy sử dụng tác vụ 340 50Thao tác này sẽ chạy chương trình 341 của bạn, chương trình này sẽ kiểm tra các ràng buộc Python mới mà bạn đã tạo bằng 70. Điều đó hoàn thành phần viết và sử dụng các liên kết Python 70 của bạnLoại bỏ các quảng cáoĐiểm mạnh và điểm yếuCó vẻ như 72 yêu cầu ít thao tác hơn ví dụ 70 mà bạn vừa thấy. Mặc dù điều này đúng với trường hợp sử dụng này, nhưng 70 mở rộng quy mô cho các dự án lớn hơn tốt hơn nhiều so với 72 do tự động hóa phần lớn gói chức năng 70 cũng tạo ra trải nghiệm người dùng hoàn toàn khác. 72 cho phép bạn tải trực tiếp thư viện C có sẵn vào chương trình Python của bạn. Mặt khác, 70 tạo một mô-đun Python mới có thể được tải như các mô-đun Python khácNgoài ra, với phương pháp API ngoài luồng mà bạn đã sử dụng ở trên, thời gian phạt để tạo các ràng buộc Python được thực hiện một lần khi bạn xây dựng nó và không xảy ra mỗi khi bạn chạy mã của mình. Đối với các chương trình nhỏ, đây có thể không phải là vấn đề lớn, nhưng 70 cũng mở rộng quy mô tốt hơn cho các dự án lớn hơn theo cách nàyGiống như 72, sử dụng 70 chỉ cho phép bạn giao tiếp trực tiếp với các thư viện C. Các thư viện C++ yêu cầu rất nhiều công việc để sử dụng. Trong phần tiếp theo, bạn sẽ thấy một công cụ ràng buộc Python tập trung vào C++$ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 354 354 thực hiện một cách tiếp cận hoàn toàn khác để tạo các liên kết Python. Ngoài việc chuyển trọng tâm từ C sang C++, nó còn sử dụng C++ để chỉ định và xây dựng mô-đun, cho phép nó tận dụng lợi thế của các công cụ lập trình siêu dữ liệu trong C++. Giống như 70, các liên kết Python được tạo từ 354 là một mô-đun Python đầy đủ có thể được nhập và sử dụng trực tiếp 354 được mô phỏng theo thư viện 359 và có giao diện tương tự. Tuy nhiên, nó hạn chế sử dụng C ++ 11 trở lên, cho phép nó đơn giản hóa và tăng tốc mọi thứ so với Boost, hỗ trợ mọi thứNó được cài đặt như thế nàoPhần Các bước đầu tiên của tài liệu 354 hướng dẫn bạn cách tải xuống và xây dựng các trường hợp thử nghiệm cho 354. Mặc dù điều này dường như không bắt buộc, nhưng thực hiện qua các bước này sẽ đảm bảo bạn đã thiết lập các công cụ C++ và Python phù hợpGhi chú. Hầu hết các ví dụ cho 354 sử dụng 363, đây là một công cụ tốt để xây dựng các dự án C và C++. Tuy nhiên, đối với bản trình diễn này, bạn sẽ tiếp tục sử dụng công cụ 3, công cụ này tuân theo hướng dẫn trong phần Xây dựng thủ công của tài liệuBạn sẽ muốn cài đặt công cụ này vào môi trường ảo của mình 51 354 là một thư viện toàn tiêu đề, tương tự như phần lớn Boost. Điều này cho phép 8 cài đặt nguồn C++ thực sự cho thư viện trực tiếp vào môi trường ảo của bạnGọi hàmTrước khi đi sâu vào, xin lưu ý rằng bạn đang sử dụng một tệp nguồn C++ khác, 367, thay vì tệp C mà bạn đã sử dụng cho các ví dụ trước. Chức năng về cơ bản là giống nhau trong cả hai ngôn ngữViết các ràng buộcTương tự như 70, bạn cần tạo một số mã để cho công cụ biết cách xây dựng các liên kết Python của bạn. Không giống như 70, mã này sẽ bằng C++ thay vì Python. May mắn thay, có một lượng mã tối thiểu được yêu cầu 52Hãy xem xét từng phần một, vì 354 chứa rất nhiều thông tin trong một vài dòngHai dòng đầu tiên bao gồm tệp 371 và tệp tiêu đề cho thư viện C++ của bạn, 372. Sau đó, bạn có macro 373. Điều này mở rộng thành một khối mã C++ được mô tả rõ ràng trong nguồn 354
Điều này có ý nghĩa gì đối với bạn, trong ví dụ này, bạn đang tạo một mô-đun có tên là 376 và phần còn lại của mã sẽ sử dụng 377 làm tên của đối tượng 375. Ở dòng tiếp theo, bên trong hàm C++ mà bạn đang xác định, bạn tạo một chuỗi tài liệu cho mô-đun. Mặc dù điều này là tùy chọn, nhưng thật tuyệt khi làm cho mô-đun của bạn giống Pythonic hơnCuối cùng, bạn có cuộc gọi 379. Điều này sẽ xác định một hàm được xuất bởi các liên kết Python mới của bạn, nghĩa là nó sẽ hiển thị từ Python. Trong ví dụ này, bạn đang truyền ba tham số
Bây giờ bạn đã có mã cho các liên kết Python, hãy xem cách bạn có thể xây dựng mã này thành một mô-đun Python Xây dựng các ràng buộc PythonCông cụ bạn sử dụng để xây dựng các liên kết Python trong 354 chính là trình biên dịch C++. Bạn có thể cần sửa đổi các giá trị mặc định cho trình biên dịch và hệ điều hành của mìnhĐể bắt đầu, bạn phải xây dựng thư viện C++ mà bạn đang tạo ràng buộc. Đối với một ví dụ nhỏ này, bạn có thể xây dựng thư viện 384 trực tiếp vào thư viện liên kết Python. Tuy nhiên, đối với hầu hết các ví dụ trong thế giới thực, bạn sẽ có một thư viện có sẵn mà bạn muốn bọc, vì vậy bạn sẽ xây dựng thư viện 384 riêng. Bản dựng là lời gọi tiêu chuẩn tới trình biên dịch để xây dựng thư viện dùng chung 53Chạy cái này với 386 tạo ra 387 54Mặt khác, bản dựng cho các liên kết Python yêu cầu một số chi tiết đặc biệt 55Hãy đi qua từng dòng này. Dòng 3 chứa các cờ trình biên dịch C++ khá chuẩn cho biết một số chi tiết, bao gồm việc bạn muốn tất cả các cảnh báo bị bắt và coi là lỗi, rằng bạn muốn có một thư viện dùng chung và rằng bạn đang sử dụng C++11 Dòng 4 là bước đầu tiên của phép thuật. Nó gọi mô-đun 388 để nó tạo ra các đường dẫn 389 thích hợp cho 354. Bạn có thể chạy lệnh này trực tiếp trên bàn điều khiển để xem những gì nó làm 56Đầu ra của bạn phải tương tự nhưng hiển thị các đường dẫn khác nhau Trong dòng 5 của cuộc gọi biên dịch của bạn, bạn có thể thấy rằng bạn cũng đang thêm đường dẫn đến nhà phát triển Python 391. Mặc dù chúng tôi khuyên bạn không nên liên kết với chính thư viện Python, nguồn cần một số mã từ 392 để phát huy tác dụng kỳ diệu của nó. May mắn thay, mã mà nó sử dụng khá ổn định trên các phiên bản PythonDòng 5 cũng sử dụng 393 để thêm thư mục hiện tại vào danh sách đường dẫn 389. Điều này cho phép giải quyết dòng 395 trong mã trình bao bọc của bạnDòng 6 chỉ định tên tệp nguồn của bạn, đó là 396. Sau đó, trên dòng 7, bạn thấy một số ma thuật xây dựng khác đang xảy ra. Dòng này chỉ định tên của tệp đầu ra. Python có một số ý tưởng cụ thể về đặt tên mô-đun, bao gồm phiên bản Python, kiến trúc máy và các chi tiết khác. Python cũng cung cấp một công cụ để trợ giúp điều này có tên là 397 57Bạn có thể cần sửa đổi lệnh nếu đang sử dụng phiên bản Python khác. Kết quả của bạn có thể sẽ thay đổi nếu bạn đang sử dụng một phiên bản Python khác hoặc đang sử dụng một hệ điều hành khác Dòng cuối cùng của lệnh xây dựng của bạn, dòng 8, trỏ trình liên kết vào thư viện 398 mà bạn đã xây dựng trước đó. Phần 399 yêu cầu trình liên kết thêm thông tin vào thư viện dùng chung để giúp hệ điều hành tìm thấy 398 khi chạy. Cuối cùng, bạn sẽ nhận thấy rằng chuỗi này được định dạng bằng 501 và 502. Bạn sẽ sử dụng lại chức năng này khi xây dựng mô-đun liên kết Python của mình với 503 trong phần tiếp theoChạy lệnh này để xây dựng các ràng buộc của bạn 58Đó là nó. Bạn đã xây dựng các liên kết Python của mình với 354. Đã đến lúc kiểm tra nóGọi chức năng của bạnTương tự như ví dụ về 70 ở trên, khi bạn đã hoàn thành công việc nặng nhọc là tạo các ràng buộc Python, việc gọi hàm của bạn trông giống như mã Python bình thường 59Vì bạn đã sử dụng 376 làm tên mô-đun của mình trong macro 373, nên đó là tên bạn nhập. Trong cuộc gọi 379, bạn đã yêu cầu 354 xuất hàm 384 dưới dạng 380, vì vậy đó là những gì bạn sử dụng để gọi nó từ PythonBạn cũng có thể kiểm tra nó với 3 0Đó là những gì 354 trông giống như. Tiếp theo, bạn sẽ thấy khi nào và tại sao 354 là công cụ phù hợp cho công việcLoại bỏ các quảng cáoĐiểm mạnh và điểm yếu 354 tập trung vào C++ thay vì C, điều này làm cho nó khác với 72 và 70. Nó có một số tính năng khiến nó trở nên khá hấp dẫn đối với các thư viện C++
Như đã nói, bạn cần thực hiện một chút thiết lập và cấu hình để thiết lập và chạy 354. Việc cài đặt và xây dựng chính xác có thể hơi phức tạp, nhưng một khi đã hoàn tất, nó có vẻ khá vững chắc. Ngoài ra, 354 yêu cầu bạn sử dụng ít nhất C++ 11 hoặc mới hơn. Đây không phải là một hạn chế lớn đối với hầu hết các dự án, nhưng nó có thể là một sự cân nhắc cho bạnCuối cùng, mã bổ sung bạn cần viết để tạo các liên kết Python nằm trong C++ chứ không phải Python. Đây có thể là vấn đề hoặc không đối với bạn, nhưng nó khác với các công cụ khác mà bạn đã xem tại đây. Trong phần tiếp theo, bạn sẽ chuyển sang 503, cách tiếp cận vấn đề này hoàn toàn khác$ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 503Cách tiếp cận mà 503 sử dụng để tạo các liên kết Python sử dụng ngôn ngữ giống Python để xác định các liên kết và sau đó tạo mã C hoặc C++ có thể được biên dịch vào mô-đun. Có một số phương pháp để xây dựng các liên kết Python với 503. Cách phổ biến nhất là sử dụng 524 từ 525. Đối với ví dụ này, bạn sẽ sử dụng công cụ 3, công cụ này sẽ cho phép bạn chơi với các lệnh chính xác được chạyNó được cài đặt như thế nào 503 là một mô-đun Python có thể được cài đặt vào môi trường ảo của bạn từ PyPI 1Một lần nữa, nếu bạn đã cài đặt tệp 305 vào môi trường ảo của mình, thì tệp này sẽ ở đó rồi. Bạn có thể lấy một bản sao của 305 bằng cách nhấp vào liên kết bên dướiNhận mã mẫu. Nhấp vào đây để lấy mã mẫu mà bạn sẽ sử dụng để tìm hiểu về Python Bindings trong hướng dẫn này Điều đó sẽ giúp bạn sẵn sàng làm việc với 503Gọi hàmĐể xây dựng các ràng buộc Python của bạn với 503, bạn sẽ làm theo các bước tương tự như những gì bạn đã sử dụng cho 70 và 354. Bạn sẽ viết các liên kết, xây dựng chúng và sau đó chạy mã Python để gọi chúng. 503 có thể hỗ trợ cả C và C++. Đối với ví dụ này, bạn sẽ sử dụng thư viện 384 mà bạn đã sử dụng cho ví dụ 354 ở trênViết các ràng buộcHình thức phổ biến nhất để khai báo một mô-đun trong 503 là sử dụng tệp 538 2Có hai phần ở đây
Ngôn ngữ được sử dụng ở đây là sự kết hợp đặc biệt giữa C, C++ và Python. Tuy nhiên, nó sẽ trông khá quen thuộc với các nhà phát triển Python, vì mục tiêu là làm cho quá trình này dễ dàng hơn Phần đầu tiên với 544 nói với 503 rằng các khai báo hàm bên dưới cũng được tìm thấy trong tệp 372. Điều này hữu ích để đảm bảo rằng các ràng buộc Python của bạn được xây dựng dựa trên các khai báo giống như mã C++ của bạn. Phần thứ hai trông giống như một hàm Python thông thường—bởi vì nó là. Phần này tạo một hàm Python có quyền truy cập vào hàm C++ 384Bây giờ bạn đã xác định được các liên kết Python, đã đến lúc xây dựng chúng Xây dựng các ràng buộc PythonQuy trình xây dựng cho 503 có những điểm tương đồng với quy trình bạn đã sử dụng cho 354. Trước tiên, bạn chạy 503 trên tệp 538 để tạo tệp 552. Khi bạn đã hoàn thành việc này, bạn biên dịch nó với cùng chức năng mà bạn đã sử dụng cho 354 3Bạn bắt đầu bằng cách chạy 554 trên tệp 538 của mình. Có một vài tùy chọn bạn sử dụng trên lệnh này
Khi tệp C++ được tạo, bạn sử dụng trình biên dịch C++ để tạo các ràng buộc Python, giống như bạn đã làm cho 354. Lưu ý rằng lời gọi để tạo thêm các đường dẫn 389 bằng công cụ 388 vẫn nằm trong chức năng đó. Nó sẽ không ảnh hưởng gì ở đây, vì nguồn của bạn sẽ không cần những thứ đóChạy tác vụ này trong 3 tạo ra kết quả này 4Bạn có thể thấy nó build thư viện 384 sau đó build module 554 để bọc nó. Bây giờ bạn có các liên kết Python 503. (Thử nói nhanh đi…) Đã đến lúc thử nghiệmGọi chức năng của bạnMã Python để gọi các liên kết Python mới của bạn khá giống với mã bạn đã sử dụng để kiểm tra các mô-đun khác 5Dòng 2 nhập mô-đun ràng buộc Python mới của bạn và bạn gọi 542 trên dòng 7. Hãy nhớ rằng tệp 538 đã cung cấp trình bao bọc Python vào khoảng 540 và đổi tên thành 570. Sử dụng gọi để chạy thử nghiệm của bạn tạo ra như sau 6Bạn nhận được kết quả tương tự như trước đây Loại bỏ các quảng cáoĐiểm mạnh và điểm yếu 503 là một công cụ tương đối phức tạp có thể cung cấp cho bạn mức độ kiểm soát sâu khi tạo các liên kết Python cho C hoặc C++. Mặc dù bạn không đề cập sâu ở đây, nhưng nó cung cấp một phương pháp Python-esque để viết mã điều khiển GIL theo cách thủ công, có thể tăng tốc đáng kể một số loại sự cốTuy nhiên, ngôn ngữ Python-esque đó không hoàn toàn là Python, do đó, có một chút đường cong học tập khi bạn bắt đầu tăng tốc trong việc tìm ra phần nào của C và Python phù hợp với vị trí nào. Giải pháp khácTrong khi nghiên cứu hướng dẫn này, tôi đã tìm thấy một số công cụ và tùy chọn khác nhau để tạo các liên kết Python. Mặc dù tôi giới hạn tổng quan này ở một số tùy chọn phổ biến hơn, nhưng có một số công cụ khác mà tôi tình cờ tìm thấy. Danh sách dưới đây không đầy đủ. Nó chỉ đơn thuần là lấy mẫu các khả năng khác nếu một trong những công cụ trên không phù hợp với dự án của bạn $ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 572 572 tạo các ràng buộc Python cho C hoặc C++ và được viết bằng Python. Nó được nhắm mục tiêu tạo mã C hoặc C ++ có thể đọc được, điều này sẽ đơn giản hóa các vấn đề gỡ lỗi. Không rõ liệu điều này đã được cập nhật gần đây chưa, vì tài liệu liệt kê Python 3. 4 là phiên bản thử nghiệm mới nhất. Đã có những bản phát hành hàng năm trong vài năm qua, tuy nhiên$ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 574 574 có giao diện tương tự như 354 mà bạn đã thấy ở trên. Đó không phải là sự trùng hợp ngẫu nhiên, vì 354 dựa trên thư viện này. 574 được viết bằng C++ đầy đủ và hỗ trợ hầu hết, nếu không muốn nói là tất cả, các phiên bản C++ trên hầu hết các nền tảng. Ngược lại, 354 tự giới hạn trong C++ hiện đại$ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 580 580 là bộ công cụ để tạo các liên kết Python được phát triển cho dự án PyQt. Nó cũng được dự án wxPython sử dụng để tạo các ràng buộc của chúng. Nó có một công cụ tạo mã và một mô-đun Python bổ sung cung cấp các chức năng hỗ trợ cho mã được tạo$ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 582 583 là một công cụ thú vị có mục tiêu thiết kế hơi khác so với những gì bạn đã thấy cho đến nay. Theo lời của tác giả gói
$ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 584 584 là một công cụ để tạo các liên kết Python được phát triển cho dự án PySide được liên kết với dự án Qt. Mặc dù nó được thiết kế như một công cụ cho dự án đó, nhưng tài liệu chỉ ra rằng nó không dành riêng cho Qt- hay PySide và có thể sử dụng được cho các dự án khác$ invoke --list Available tasks: all Build and run all tests build-cffi Build the CFFI Python bindings build-cmult Build the shared library for the sample C code build-cppmult Build the shared library for the sample C++ code build-cython Build the cython extension module build-pybind11 Build the pybind11 wrapper library clean Remove any built objects test-cffi Run the script to test CFFI test-ctypes Run the script to test ctypes test-cython Run the script to test Cython test-pybind11 Run the script to test PyBind11 586 586 là một công cụ khác với bất kỳ công cụ nào khác được liệt kê ở đây. Nó là một công cụ chung được sử dụng để tạo các liên kết với các chương trình C và C++ cho nhiều ngôn ngữ khác, không chỉ Python. Khả năng tạo ràng buộc cho các ngôn ngữ khác nhau này có thể khá hữu ích trong một số dự án. Tất nhiên, nó đi kèm với một chi phí liên quan đến sự phức tạp.Sự kết luậnchúc mừng. Bây giờ bạn đã có tổng quan về một số tùy chọn khác nhau để tạo các liên kết Python. Bạn đã học về sắp xếp dữ liệu và các vấn đề bạn cần xem xét khi tạo liên kết. Bạn đã thấy những gì cần thiết để có thể gọi một hàm C hoặc C++ từ Python bằng các công cụ sau
Bây giờ bạn đã biết rằng, trong khi 72 cho phép bạn tải trực tiếp tệp DLL hoặc thư viện dùng chung, ba công cụ còn lại thực hiện thêm một bước, nhưng vẫn tạo ra một mô-đun Python đầy đủ. Như một phần thưởng, bạn cũng đã chơi một chút với công cụ 3 để chạy các tác vụ dòng lệnh từ Python. Bạn có thể lấy tất cả mã bạn đã thấy trong hướng dẫn này bằng cách nhấp vào liên kết bên dướiNhận mã mẫu. Nhấp vào đây để lấy mã mẫu mà bạn sẽ sử dụng để tìm hiểu về Python Bindings trong hướng dẫn này Bây giờ hãy chọn công cụ yêu thích của bạn và bắt đầu xây dựng các liên kết Python đó. Đặc biệt cảm ơn Loic Domaigne đã đánh giá kỹ thuật bổ sung cho hướng dẫn này Đánh dấu là đã hoàn thành 🐍 Thủ thuật Python 💌 Nhận một Thủ thuật Python ngắn và hấp dẫn được gửi đến hộp thư đến của bạn vài ngày một lần. Không có thư rác bao giờ. Hủy đăng ký bất cứ lúc nào. Được quản lý bởi nhóm Real Python Gửi cho tôi thủ thuật Python » Về Jim Anderson Jim đã lập trình trong một thời gian dài bằng nhiều ngôn ngữ. Anh ấy đã làm việc trên các hệ thống nhúng, xây dựng các hệ thống xây dựng phân tán, quản lý nhà cung cấp nước ngoài và tham gia rất nhiều cuộc họp » Thông tin thêm về JimMỗi hướng dẫn tại Real Python được tạo bởi một nhóm các nhà phát triển để nó đáp ứng các tiêu chuẩn chất lượng cao của chúng tôi. Các thành viên trong nhóm đã làm việc trong hướng dẫn này là Aldren Geir Arne Jaya Joanna Mike Bậc thầy Kỹ năng Python trong thế giới thực Với quyền truy cập không giới hạn vào Python thực Tham gia với chúng tôi và có quyền truy cập vào hàng nghìn hướng dẫn, khóa học video thực hành và cộng đồng các Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bậc thầy Kỹ năng Python trong thế giới thực Tham gia với chúng tôi và có quyền truy cập vào hàng ngàn hướng dẫn, khóa học video thực hành và cộng đồng Pythonistas chuyên gia Nâng cao kỹ năng Python của bạn » Bạn nghĩ sao? Đánh giá bài viết này Tweet Chia sẻ Chia sẻ EmailBài học số 1 hoặc điều yêu thích mà bạn đã học được là gì? Mẹo bình luận. Những nhận xét hữu ích nhất là những nhận xét được viết với mục đích học hỏi hoặc giúp đỡ các sinh viên khác. Nhận các mẹo để đặt câu hỏi hay và nhận câu trả lời cho các câu hỏi phổ biến trong cổng thông tin hỗ trợ của chúng tôi Làm cách nào để chuyển đổi C sang Python?Đối với các chuỗi C được biểu thị dưới dạng một cặp char *, int , quyết định xem có hay không – chuỗi được trình bày dưới dạng chuỗi byte thô hoặc dưới dạng chuỗi Unicode. PyObject *obj = PyUnicode_FromWideChar(w, len); Dữ liệu từ C phải được giải mã rõ ràng thành một chuỗi theo một số codec.
Python có thể đọc mã C không?Việc triển khai mặc định của python được viết bằng lập trình C và được gọi là CPython. Vì vậy việc sử dụng các hàm C trong chương trình python không phải là hiếm .
Python có thể nhập thư viện C không?ctypes cho phép bạn tải trực tiếp thư viện C có sẵn vào chương trình Python của mình .
Python có thể tương tác với C không?Chúng tôi có thể trích dẫn Cython hoặc Numba biến mã Python thành mã C thực thi được và yêu cầu bổ sung tối thiểu vào mã Python hiện có . Ngoài ra còn có Ctypes cung cấp các kiểu dữ liệu tương thích với C, và cho phép gọi hàm từ các thư viện bên ngoài, e. g. gọi các hàm C được biên dịch trước. |