ฉันต้องการตอบคำถามง่ายๆ…
FFI ใน Ruby คืออะไร ?
FFI ย่อมาจาก “Foreign Function Interface”
เป็นวิธีการใช้ฟังก์ชันที่กำหนดไว้ในภาษาการเขียนโปรแกรมอื่น .
โมดูล FFI ของ Ruby ช่วยให้คุณเข้าถึงไลบรารีและโค้ดภายนอกที่คุณไม่มีได้
เรามักใช้สิ่งนี้เพื่อทำงานกับรหัส C
ตัวอย่าง ได้แก่ :
- rb-inotify
- ruby-vips
- ruby-nfc
คุณสามารถเขียนโปรแกรมของคุณเองที่ใช้ FFI ด้วยความช่วยเหลือของโมดูล FFI
อย่างไร
มาดูตัวอย่างโค้ดกัน!
ข้อมูลเบื้องต้นเกี่ยวกับ FFI:การโหลดและการนำเข้าฟังก์ชัน
คุณทำงานกับ FFI ได้โดยการรวมฟังก์ชันต่างๆ ไว้ในโมดูลที่คุณสร้างขึ้น
ถูกใจสิ่งนี้ :
ต้องการ 'ffi'module A ขยาย FFI::Libraryend
จากนั้น ภายในโมดูล เราจะโหลดไลบรารีโดยใช้ ffi_lib
วิธีการ
ไลบรารี C เช่น "DLL" ใน Windows หรือ "SO" ใน Linux จะส่งออกรายการ "สัญลักษณ์" หรือคำจำกัดความของฟังก์ชันที่โปรแกรมทำให้ผู้อื่นใช้งานได้
ต้องใช้ “libc“ ซึ่งเป็นไลบรารีมาตรฐานของ C
ตามนี้ :
โมดูล A ขยาย FFI::Library ffi_lib 'c'end
ตอนนี้ :
คุณสามารถนำเข้าฟังก์ชันเฉพาะจากไลบรารีนี้เป็นเมธอดของ Ruby ได้
ด้วย attach_function
วิธีการ
นี่คือตัวอย่าง :
โมดูล A ขยาย FFI::Library ffi_lib 'c' attach_function :strlen, [:string], :intendA.strlen("abc")# 3
วิธีนี้ทำงานอย่างไร
ก่อนอื่น เรารู้ว่ามีฟังก์ชันในภาษา C เรียกว่า strlen
ฟังก์ชันนี้ใช้ chars *
เป็นข้อโต้แย้ง
chars *
แปลเป็น String
ในทับทิม
แล้ว…
strlen
นี้ ฟังก์ชั่นส่งกลับค่าซึ่งเป็นความยาวของสตริง
กล่าวอีกนัยหนึ่ง attach_function
รับ 3 พารามิเตอร์:
- ชื่อของฟังก์ชัน C
- อาร์เรย์ของประเภทอาร์กิวเมนต์
- ประเภทการคืนสินค้า
คุณจะต้องอ่านเอกสารประกอบเพื่อค้นหาว่าฟังก์ชันเฉพาะประเภทใดใช้งานได้
ถึงเวลาสำหรับตัวอย่างอื่นแล้ว!
สร้างเครื่องเล่นสื่อของคุณเอง
คุณจะพบห้องสมุดที่น่าสนใจมากมายให้เล่นด้วย
ใน Linux ส่วนใหญ่จะอยู่ภายใต้ /usr/lib/
ไดเร็กทอรีที่ขึ้นต้นด้วย “lib” ในชื่อและลงท้ายด้วยนามสกุล “so”
ลงรายการตามนี้ :
ls /usr/lib/lib*.so
สำหรับตัวอย่างนี้ เราจะใช้ไลบรารีโปรแกรมเล่นสื่อของ VLC :
/usr/lib/libvlc.so
เป้าหมายของเราคือโหลดไฟล์ mp3 แล้วเล่นได้เลย!
มาเริ่มกันเลย :
ต้องการ 'ffi'module VLC ขยาย FFI::Library ffi_lib 'vlc' attach_function :libvlc_get_version, [], :stringend
วิธีนี้ช่วยให้คุณทดสอบได้ว่าไลบรารีโหลดถูกต้องหรือไม่ จากนั้นพิมพ์เวอร์ชันของไลบรารี
ถูกใจสิ่งนี้ :
VLC.libvlc_get_version# "3.0.6 Vetinari"
คุณสามารถตั้งชื่อที่กำหนดเองให้กับเมธอดเหล่านี้ได้โดยการเพิ่มพารามิเตอร์ตัวที่ 4
ตัวอย่าง :
attach_function :get_version, :libvlc_get_version, [], :string
คุณก็ทำได้ :
VLC.get_version
เราต้องเล่น mp3 อะไรตอนนี้
ถ้าเราดูที่เอกสารประกอบ libvlc_media_player_play
ฟังชั่นดูเหมือนเป็นแนวทาง
ฟังก์ชันนี้ต้องการเครื่องเล่นสื่อ “วัตถุ”
โปรแกรมเล่นสื่อต้องการสื่อ และสื่อต้องการอินสแตนซ์ VLC
นี่คือกระบวนการ :
อินสแตนซ์ VLC -> สื่อ -> media_player -> เล่น
ฉันรวมสิ่งนี้เข้าด้วยกันโดยอ่านเอกสารสำหรับ libVLC
.
ตัวชี้หน่วยความจำใน Ruby???
ใน C คุณจะไม่พบวัตถุใดๆ เลย ทุกอย่างได้รับการจัดการด้วยพอยน์เตอร์หน่วยความจำ
ตัวชี้หน่วยความจำคือที่อยู่หน่วยความจำที่มีข้อมูล
มาดูตัวอย่างโค้ดกัน :
โมดูล VLC ขยาย FFI::Library ffi_lib 'vlc' attach_function :get_version, :libvlc_get_version, [], :string attach_function :new, :libvlc_new, [:int, :int], :pointerendVLC.new(0, 0) # FFI::Pointer address=0x000055c6f04ae7b0
จากการเรียก VLC.new
เราได้รับตัวชี้
เราต้องส่งต่อไปยังฟังก์ชัน C อื่นๆ ที่ต้องการ
ตอนนี้ :
ตัวอย่างแบบเต็มและวิธีการใช้งาน
โมดูล VLC ขยาย 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, [:int Attach_function :stop, :libvlc_media_player_stop, [:int Attach_], ฟังก์ชัน :libvlc_media_player_pause, [:ตัวชี้], :ตั้งใจ
เปิดเพลงก็พอแล้ว :
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)ก่อน>การดำเนินการนี้จะเล่นเพลงโดยไม่ต้องเปิดอินเทอร์เฟซแบบภาพใดๆ
คุณสามารถสร้างเว็บอินเตอร์เฟสของคุณเองได้
ให้มันลอง!
สรุป
คุณได้เรียนรู้เกี่ยวกับพลังอันน่าทึ่งของ
FFI
! โมดูล Ruby ที่ให้คุณใช้ไลบรารีภายนอกราวกับว่าเป็นส่วนหนึ่งของภาษานั้นเองกรุณาแบ่งปันบทความนี้เพื่อให้คนอื่น ๆ สามารถเพลิดเพลินกับมันได้ 🙂
ขอบคุณสำหรับการอ่าน!