100 days I learn - day 1 - ctypes


Posted on 27 Feb 2019 by Tulip Tulip

Thiên hành kiện, quân tử dĩ tự cường bất tức.

Trời đất biến chuyển mạnh mẽ, người quân tử phải không ngừng tự cường.

Mỗi ngày đi làm 24h, nếu không học được điều gì mới thì đó là 1 điều đáng tiếc. Mình thực sự cũng đúc kết được rất nhiều điều mỗi ngày, mà cái nhớ, cái thì trôi tuột đi, đó là một điều đáng tiếc. Từ giờ, mình sẽ viết series này mỗi khi học được điều gì đó mới trong ngày (hy vọng ngày nào cũng có thể viết).

Vậy hôm nay viết về điều gì? Viết về chuyện làm mình đau đầu mấy hôm trước, là chuyện về ctypes.

Bài toán

Bài toán mình gặp phải khi đó là: khách hàng có 1 package A xử lý job X có sẵn, tuy nhiên package này viết bằng C++. Bây giờ mình cần viết 1 cái demo có sử dụng package này để minh họa cho việc package A chạy tốt.

Vấn đề xảy ra là mình hoàn toàn không biết gì về C++, ngôn ngữ mình tự tin chỉ có python. Tới đây có 2 lựa chọn cho mình:

  • viết demo sử dụng C++
  • viết demo bằng python, và bằng 1 cách nào đó móc được cái code C++ kia vào code mình.

Dù được mọi người khuyên nên làm cách 1, nhưng mình có thể tưởng tượng đủ sự nhiêu khê khi debug (và thực tế debug bằng python cũng làm mình gần chết). Mình đã thử Google, sau đó thấy 1 vài giải pháp là sử dụng swig/boost, nhưng đấy đều là các giải pháp hơi phức tạp (deadline mình rất gấp, chỉ có ~2 ngày). Sau 1 cú gọi điện cầu cứu đại ca sếp mình ở tít Hà Nội, thì sếp gợi ý mình dùng ctypes.

Thực hiện

Quá trình test ctypes rất nuột nà. Về cơ bản, thì việc dùng ctypes sẽ như thế này:

  • tạo ra file .dll cho file C++
  • đọc file .dll đó bằng ctypes
  • gọi hàm ctypes và chạy thôi

Nhưng đúng là lúc chạy cũng lắm nhiêu khê. Nhiêu khê nhất là mấy vấn đề như này:

  • dạng arg truyền vào hàm C++. Ví dụ như string phải convert qua dạng bytes, encode utf-8 mới truyền được.
  • Error rất chung chung: OSError chẳng hạn. Kiểu wtf và debug cũng mệt
  • nếu hàm C++ truyền ra type lạ không có tương thích trong python thì quá mệt, thực ra mình cũng chưa biết cách giải quyết trong trường hợp này.

Nhưng cuối cùng cũng xong, sau khi mình đã phải viết 1 hàm mới, may mà các hàm cần show demo thì trong file header nên không sao.

Kết luận

ctypes là package built-in của python, và nó giải quyết kahs tốt bài toán này trong trường hợp đơn giản. Nếu mọi thứ phức tạp, thực sự bạn nên tìm cách viết demo native. Ngoài ra thì nếu viết được kiểu api thì tốt nhất, đỡ lằng nhằng kiểu này.

Đây không phải cái mình học hôm nay, nhưng nó là 1 thứ mình học gần đây rất đáng giá để ghi chép lại.

Cheer!