Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Giải Thích Ruby FFI: Phát MP3 Với VLC – Hướng Dẫn Thực Hành

Tôi muốn trả lời một câu hỏi đơn giản... FFI trong Ruby là gì? FFI = "Foreign Function Interface". Cách dùng hàm định nghĩa trong ngôn ngữ lập trình khác. Module FFI Ruby cho truy cập thư viện & code bên ngoài bạn không có cách khác. Thường dùng làm việc với C code. Ví dụ: rb-inotify, ruby-vips, ruby-nfc. Bạn viết chương trình dùng FFI với giúp module FFI. Làm sao? Xem vài ví dụ code!

FFI Basics: Load & Import Functions

Làm việc FFI bằng include functions vào module bạn tạo. Như:

 require 'ffi'
module A
  extend FFI::Library
end 

Bên trong module, load library dùng ffi_lib. Thư viện C, như "DLL" Windows, hoặc "SO" Linux, export danh sách "symbols", hoặc định nghĩa hàm chương trình làm available cho người khác dùng. Require "libc", thư viện chuẩn C. Cách:

 module A
  extend FFI::Library
  ffi_lib 'c'
end 

Bây giờ: Import hàm cụ thể từ library này như Ruby method. Với attach_function. Ví dụ:

 module A
  extend FFI::Library
  ffi_lib 'c'
  attach_function :strlen, [:string], :int
end
A.strlen("abc") # 3 

Cơ chế: Biết có hàm C tên strlen, nhận chars * argument. chars * dịch sang String Ruby. Hàm strlen trả về độ dài string. attach_function nhận 3 tham số: 1. Tên hàm C 2. Mảng kiểu argument 3. Kiểu trả về. Phải đọc doc tìm kiểu hàm cụ thể dùng. Ví dụ khác!

Xây Dựng Media Player Của Riêng Bạn

Tìm nhiều library thú vị. Linux, phần lớn dưới /usr/lib/, tên bắt đầu "lib" & kết thúc "so". Liệt kê: ls /usr/lib/lib*.so. Ví dụ này dùng thư viện media player VLC: /usr/lib/libvlc.so. Mục tiêu: load mp3 & play! Bắt đầu:

 require 'ffi'
module VLC
  extend FFI::Library
  ffi_lib 'vlc'
  attach_function :libvlc_get_version, [], :string
end 

Test library load đúng & in version. Như: VLC.libvlc_get_version # "3.0.6 Vetinari". Đặt tên custom cho method bằng tham số 4. Ví dụ: attach_function :get_version, :libvlc_get_version, [], :string. Rồi VLC.get_version. Cần gì để play mp3? Xem doc, libvlc_media_player_play trông như cách. Hàm này cần media player "object". Media player cần media, media cần VLC instance. Quy trình: VLC instance -> media -> media_player -> play. Tôi ghép từ doc libVLC.

Con Trỏ Bộ Nhớ Trong Ruby???

Trong C không tìm object, mọi thứ dùng con trỏ bộ nhớ. Con trỏ = địa chỉ bộ nhớ có data. Xem code:

 module VLC
  extend FFI::Library
  ffi_lib 'vlc'
  attach_function :get_version, :libvlc_get_version, [], :string
  attach_function :new, :libvlc_new, [:int, :int], :pointer
end
VLC.new(0, 0) # FFI::Pointer address=0x000055c6f04ae7b0 

Kết quả VLC.new là con trỏ. Phải pass cho hàm C khác cần nó. Bây giờ: Ví dụ đầy đủ & cách dùng.

 module VLC
  extend FFI::Library
  ffi_lib 'vlc'
  attach_function :version, :libvlc_get_version, [], :string
  attach_function :new, :libvlc_new, [:int, :int], :pointer
  attach_function :libvlc_media_new_path, [:pointer, :string], :pointer
  attach_function :libvlc_media_player_new_from_media, [:pointer], :pointer
  attach_function :play, :libvlc_media_player_play, [:pointer], :int
  attach_function :stop, :libvlc_media_player_stop, [:pointer], :int
  attach_function :pause, :libvlc_media_player_pause, [:pointer], :int
end 

Đủ chơi nhạc:

 vlc = VLC.new(0, 0)
media = VLC.libvlc_media_new_path(vlc, "/home/jesus/Downloads/meditation.mp3")
player = VLC.libvlc_media_player_new_from_media(media)
VLC.play(player) 
Phát nhạc, không mở giao diện visual. Có thể build web interface trên này. Thử đi!

Tóm Tắt

Bạn đã học sức mạnh tuyệt vời của FFI! Module Ruby cho phép dùng thư viện bên ngoài như thể chúng là phần của ngôn ngữ. Hãy chia sẻ để nhiều người tận hưởng 🙂 Cảm ơn bạn đã đọc!