Upgrade to Pro — share decks privately, control downloads, hide ads and more …

php_mecabをFFIで実装してみよう

 php_mecabをFFIで実装してみよう

PHPカンファレンス2022の発表資料です。
かつて自分がPHP MeCab Extensionを実装したときはC言語でバインディングを書くのが一般的な方法でした。
しかしPHP 7.4からはFFI (Foreign Function Interface) が導入され、C言語を書かなくてもC言語で書かれたライブラリが利用できるようになりました。
php_mecabをFFIを使って再実装する実例を元に、以下の解説をします。
・FFIの基本的な使い方
・メモリ管理
・FFIでできること
・FFIでできないこと

Ryusuke SEKIYAMA

September 25, 2022
Tweet

More Decks by Ryusuke SEKIYAMA

Other Decks in Programming

Transcript

  1. גࣜձࣾ3"#0ؔࢁོհ5XJUUFS!STLZ
    QIQ@NFDBCΛ
    ''*Ͱ࠶࣮૷ͯ͠ΈΑ͏
    1)1$POGFSFODF
    5SBDL

    View full-size slide

  2. ࠶࣮૷


    Ͱ͖·ͨ͠
    IUUQTHJUIVCDPNSTLZQIQ
    ff i
    NFDBC

    View full-size slide

  3. ؔࢁོհ ͖ͤ΍·ΓΎ͏͚͢
    !STLZ
    w ͔ͭͯ$ݴޠͰ࣮૷ͨ͠

    QIQ@NFDBCΛ࡞͍ͬͯ·ͨ͠
    w ࡢ೥݄ʹ3"#0 *ODʹస৬

    $BUMPHͷόοΫΤϯυ୲౰
    w ͻ͞ͼ͞ʹ࢓ࣄͰ1)1Λ࢖ͬͯ

    ͍·͢ 1)1 4ZNGPOZ

    w ͣͬͱ࣮Ոʹݘ͕͍ͨͷͰݘ೿
    w ೣ΋େ޷͖ 4PGUXBSF%FTJHOࢽͷදࢴྑ͍Ͱ͢Ͷ

    ࣗݾ঺հ
    Ωϟτϩά

    View full-size slide

  4. .F$BCͱ͸
    IUUQTUBLVHJUIVCJPNFDBC
    w ΦʔϓϯιʔεͷܗଶૉղੳΤϯδϯ
    w ߴ଎ͳಈ࡞ɺߴ͍҆ఆੑɺѻ͍΍͍͢"1*͕ૉఢ
    w .Z42-ͷશจݕࡧΠϯσοΫε༻ύʔαʔʹ࠾༻͞ΕΔͳͲɺ๛෋ͳ࣮੷

    View full-size slide

  5. ग़యϑϦʔඦՊࣄయʰ΢ΟΩϖσΟΞʢ8JLJQFEJBʣʱ
    'PSFJHOGVODUJPOJOUFSGBDFʢϑΥʔϦϯɾϑΝϯΫγϣϯɾΠϯλʔϑΣΠεɺ
    ''*ʣͱ͸ɺ͋Δϓϩάϥϛϯάݴޠ͔ΒଞͷϓϩάϥϛϯάݴޠͰఆٛ͞Εͨؔ਺ͳ
    ͲΛར༻͢ΔͨΊͷػߏɻओʹߴਫ४ݴޠ͔Β$$ͳͲͷؔ਺΍ϝιουΛݺͼग़
    ͠ɺ04ݻ༗ͷػೳͳͲΛར༻͢ΔͨΊʹ࢖༻͞ΕΔ͜ͱ͕ଟ͍ɻ

    View full-size slide

  6. 1)1ͷ''*ͱ͸

    View full-size slide

  7. 1)1''*
    ΠϯτϩμΫγϣϯ
    w 1)1͔Βಋೖ
    w IUUQTXXXQIQOFU
    f

    w $ݴޠͷ"1*Λ1VSF1)1ίʔυ͔Βݺͼग़ͤΔ
    w $ݴޠҎ֎ͷϥΠϒϥϦʹ͸ඇରԠ
    w 3VTU΍(P౳ɺ$ݴޠ޲͚ͷڞ༗ϥΠϒϥϦΛ

    ࡞ΕΔݴޠͰ࡞ͬͨؔ਺͸0,

    View full-size slide

  8. 1)1ϚχϡΞϧΑΓ
    w 1VSF1)1Ͱ$ؔ਺΍ߏ଄ମʹ
    ΞΫηεͰ͖ΔΑ
    w ;FOEFYUFOTJPO"1*ͷ஌ࣝ͸
    ͍Βͳ͍Αʢॏཁʣ
    w $ݴޠͷ஌͕ࣝ͋Δਓ޲͚ͩΑ
    w طଘͷ1)1֦ு"1*Λஔ͖׵͑
    ΔΑ͏ͳ΋ͷͰ͸ͳ͍Α
    1)1''*

    View full-size slide

  9. 1)1''*
    ;FOEFYUFOTJPO"1* $ݴޠͰॻ͘1)1ػೳ֦ு
    ͱൺֱ
    ''* ;FOEFYUFOTJPO"1*
    ֎෦ϥΠϒϥϦͷར༻ Ͱ͖Δ Ͱ͖Δ
    1)1ͦͷ΋ͷͷৼΔ෣͍มߋ Ͱ͖ͳ͍ Ͱ͖Δ
    $ݴޠͷ஌ࣝ ඞཁ ඞཁ
    Ϗϧυ༻πʔϧνΣʔϯ
    ίϯύΠϥɾϦϯΧ౳

    ෆཁ ඞཁ
    1)1ͷόʔδϣϯΞοϓରԠ
    ෆཁ
    ˞''*ʹഁյతͳมߋ͕ೖΒͳ͍ݶΓ͸
    ඞཁ

    View full-size slide

  10. جຊతͳ࢖͍ํ
    ϥΠϒϥϦͷϔομϑΝΠϧ͔Β࢖͍͍ͨ
    ίʔυΛநग़
    w ϚΫϩ͸ޮ͔ͳ͍ͷͰ஫ҙʂ
    FFI::cdef()Ͱ''*ΦϒδΣΫτΛੜ੒
    w ୈҾ਺͸ڞ༗ϥΠϒϥϦͷύε
    ''*ΦϒδΣΫτͷϝιουͱͯؔ͠਺Λ
    ݺͼग़͢
    Ҏ্ʂ
    1)1''*

    View full-size slide

  11. w $ͷߏ଄ମ͸FFI\CDataΦϒδ
    ΣΫτʹϚοϐϯά͞ΕΔ
    w ߏ଄ମͷϝϯό͸$%BUBΦϒδ
    ΣΫτͷΦʔόʔϩʔυ͞Εͨ
    ϓϩύςΟͱͯ͠ΞΫηεͰ͖Δ
    w FFI::new(T)͸
    malloc(sizeof(T))૬౰
    1)1''*
    ߏ଄ମͷαϙʔτ

    View full-size slide

  12. $ݴޠͷίʔυ͸ִ཭
    w ࢖͍͍ͨػೳ͕গͳ͍ͳΒ໰୊
    ͳ͍͕ɺେ͖ͳϥΠϒϥϦΛϥο
    ϓ͠Α͏ͱ͢Δͱ$ͷίʔυྔ͕
    ଟ͘ͳͬͯݟ௨͕͠ѱ͘ͳΔ
    w ઐ༻ͷϑΝΠϧʹִ཭͢Δͷ΋Ξ
    ϦͰ͸
    ࣮ફ5JQT

    View full-size slide

  13. จࣈྻͷ഑ྻ
    w $ؔ਺ʹ౉͢จࣈྻͷ഑ྻ͸ࣗલͰ࡞Δඞཁ͋Γ
    w ӈͷྫͰ͸FFI::arrayType()Λ࢖ͬͯchar
    *ͷ࣍ݩ഑ྻΛ࡞੒
    w 1)1ͷจࣈྻΛPXOFEͰͳ͍$%BUBʹม׵͠
    ͯ഑ྻʹ٧ΊΔ
    w "SSBZ5ZQF͸ͦͷཁૉͷॴ༗ݖΛ࣋ͨͳ͍
    ʢ࣋ͯͳ͍ʣͨΊ
    w 1)1Ͱ͸ීஈҙࣝ͠ͳ͍ψϧऴ୺Λ͖ͬͪΓͱ
    w 0XOFEͰͳ͍FFI::new()ͨ͠$%BUB͸ࣗ෼
    ͰFFI::free()͢Δ
    ࣮ફ5JQT

    View full-size slide

  14. w ܕͷͳ͍FFI\CDataͷΦʔόʔϩʔυ͞
    ΕͨϓϩύςΟʹܕΛ͚ͭΔ
    w int΍floatͷΑ͏ͳϓϦϛςΟϒܕ΍ɺ
    string˱char*͸҉໧తʹม׵͞ΕΔ
    w ߏ଄ମ΍഑ྻͷϝϯόͷchar*΁ͷ୅ೖ͸҉໧తʹ
    ม׵͞Εͳ͍౳ͷ੍໿΋͋Δ
    w surface()Ͱ͸ɺnode->surface͸ղ
    ੳݩͷจࣈྻͷઌ಄͔ΒϙΠϯλΛਐΊͨ
    ΋ͷͰɺޙΖʹ༨෼ͳ಺༰ΛؚΜͰ͍Δͷ
    Ͱඞཁͳ௕͚ͩ͞Λίϐʔ͍ͯ͠Δ
    ࣮ફ5JQT
    ߏ଄ମ͸ΫϥεͰϥοϓ

    View full-size slide

  15. w ϥοϓͨ͠ߏ଄ମΛഁغ͢Δͷ
    ͸1)1ΫϥεͷσετϥΫλͰ
    w 1)1͕ग़ͨࠒʹϦιʔεΛϥ
    οϓͨ͠ΫϥεͰߦ͍ͬͯͨͷͱ
    ಉ͡ख๏
    ࣮ફ5JQT
    σετϥΫλΛ׆༻

    View full-size slide

  16. w mecab_t*ͱmecab_node_t*
    ͷΑ͏ʹ਌ࢠؔ܎ʹ͋ΔΦϒδΣ
    ΫτΛѻ͏ͱ͖ɺ਌͕ഁغ͞Ε
    ͨঢ়ଶͰࢠʹΞΫηε͢ΔͱΤϥ
    ʔ͕ൃੜ͢Δ
    w 1)1ϨϕϧͰ͸ٯʹʮࢠ͕਌Λ
    ॴ༗͢Δʯ͜ͱͰࢠ͕ੜ͖͍ͯΔ
    ݶΓ͸਌΋ੜ͖͍ͯΔΑ͏ʹ͢Δ
    ࣮ફ5JQT
    ΦϒδΣΫτͷϥΠϑλΠϜ

    View full-size slide

  17. ࣮ࡍʹΤϥʔΛى͜͢σϞ

    View full-size slide

  18. QIQGGJNFDBC
    50%0
    w ''*ͷείʔϓػೳʹରԠ
    w ݱࡏ͸MeCab\TaggerのΠϯελϯεΛੜ੒͢Δ౓ʹ

    ͦͦ͜͜େ͖͍ίʔυͷղੳͱMJCNFDBCͷಡΈࠐΈΛߦ͍ͬͯΔ
    w FFI::load()ͰείʔϓࢦఆˍFFI::scope()Ͱݺͼग़͢͜ͱͰޮ཰Խ
    w .F$BC-BUUJDFܥ"1*ͷ࣮૷
    w ϥΠϒϥϦ࡞ऀͱͯ͠͸ͪΌΜͱػೳΛ໢ཏ͍ͨ͠

    View full-size slide

  19. ''*
    ࢖ͬͯΈͨײ૝
    w ࢥͬͨΑΓ؆୯ʹ࢖͑ͨ
    w $ίʔυͷղੳ΍ܕม׵͕͔ͬ͠Γ࡞Γࠐ·Ε͍ͯΔ
    w Φʔφʔγοϓʹ͍ͭͯ΋ͪΌΜͱߟ͑ΒΕ͍ͯΔ
    w *%&ʹΑΔิ׬͕ޮ͔ͳ͍ͷ͸໘౗
    w 1)1ϚχϡΞϧͰ͸ڧΊͷܯࠂ͞Ε͍ͯΔ͕࣮ઓ౤ೖͯ͠Α͍ͱࢥ͏
    w ग़དྷ߹͍ͷϥΠϒϥϦΛ࢖͏Ҏ֎ʹ΋ɺ1)1ʹෆ޲͖ͳߴ଎Խ͍ͨ͠ॲཧΛ3VTU΍
    (P౳Ͱॻ͍ͯ$͔Β࢖͑ΔΑ͏ʹͯ͠ɺ''*ܦ༝Ͱݺͼग़͢ͷ͸ಛʹΞϦͩͱࢥ͏

    View full-size slide

  20. ''*͸໘ന͍ʂ
    ;FOEFYUFOTJPO"1*΋େม͚ͩͲ໘ന͍Ͱ͢

    View full-size slide