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

実録mruby組み込み体験

 実録mruby組み込み体験

Fukuoka.rb 0x100 回 LT 大会 (#256)

More Decks by Misaki Shioi(塩井美咲/しおい)

Other Decks in Programming

Transcript

  1. ࠓճ΍Δ͜ͱ αʔόʔ 5$1Τίʔαʔόʔ $ ͷ࣮૷ int main(void) { // αʔόʔΞυϨε৘ใͷऔಘɹ

    // ιέοτͷ࡞੒ // ϦΫΤετͷ଴ͪड͚ // ϦΫΤετͷड͚෇͚ // ϦΫΤετͷಡΈࠐΈ // Ϩεϙϯεͷૹ৴ // ιέοτͷഁغ return 0; }
  2. ࠓճ΍Δ͜ͱ int main(void) { // αʔόʔΞυϨε৘ใͷऔಘɹ // ιέοτͷ࡞੒ // ϦΫΤετͷ଴ͪड͚

    // ϦΫΤετͷड͚෇͚ // ϦΫΤετͷಡΈࠐΈ // Ϩεϙϯεͷૹ৴ // ιέοτͷഁغ return 0; } ⬅︎ ͜Ε͕ۤखͳͷͰ ɹ3VCZͰ αʔόʔ 5$1Τίʔαʔόʔ $ ͷ࣮૷
  3. struct addrinfo server_addr_hints, *server_addr, *server_addr_tmp; int addrinfoerr; memset(&server_addr_hints, 0, sizeof(struct

    addrinfo)); server_addr_hints.ai_family = AF_INET; server_addr_hints.ai_socktype = SOCK_STREAM; server_addr_hints.ai_ fl ags = AI_PASSIVE; if ((addrinfoerr = getaddrinfo(HOST, PORT, &server_addr_hints, &server_addr)) < 0) { gai_strerror(addrinfoerr); } <$ͷ৔߹>αʔόʔΞυϨε৘ใऔಘ  // ศ্ٓ"'@*/&5ʹ͍ͯ͠·͢
  4. struct addrinfo server_addr_hints, *server_addr, *server_addr_tmp; int addrinfoerr; memset(&server_addr_hints, 0, sizeof(struct

    addrinfo)); server_addr_hints.ai_family = AF_INET; server_addr_hints.ai_socktype = SOCK_STREAM; server_addr_hints.ai_ fl ags = AI_PASSIVE; if ((addrinfoerr = getaddrinfo(HOST, PORT, &server_addr_hints, &server_addr)) < 0) { gai_strerror(addrinfoerr); } <$ͷ৔߹>αʔόʔΞυϨε৘ใऔಘ  // ศ্ٓ"'@*/&5ʹ͍ͯ͠·͢ ᶃΞυϨε৘ใͷώϯτΛ֨ೲ͢Δߏ଄ମͱ ɹΞυϨε৘ใΛ֨ೲ͢Δߏ଄ମͷͨΊͷϝϞϦྖҬΛ֬อ ᶄΞυϨε৘ใͷώϯτΛ֨ೲ͢Δߏ଄ମʹΞυϨε৘ใͷώϯτΛ֨ೲ ᶅΞυϨε৘ใͷώϯτΛ֨ೲͨ͠ߏ଄ମΛར༻ͯ͠ ɹ࠷ॳʹݟ͔ͭͬͨΞυϨε৘ใΛΞυϨε৘ใΛ֨ೲ͢Δߏ଄ମʹ֨ೲ ɹ˞͜ͷͱ͖ɺΞυϨε৘ใ͸ϦϯΫϦετʹͳ͓ͬͯΓɺ ɹɹΞυϨε৘ใΛ֨ೲ͢Δߏ଄ମ͸ଞʹར༻Ͱ͖ΔީิͱͳΔ ɹɹΞυϨε৘ใ΁ͷϙΠϯλΛ͍࣋ͬͯΔ
  5. int listener; for (server_addr_tmp = server_addr; server_addr_tmp; server_addr_tmp = server_addr_tmp->ai_next)

    { listener = socket(server_addr_tmp->ai_family, server_addr_tmp->ai_socktype, server_addr_tmp->ai_protocol); if (listener < 0) continue; if (bind(listener, server_addr_tmp->ai_addr, server_addr_tmp->ai_addrlen) < 0) { close(listener); continue; } break; } <$ͷ৔߹>αʔόʔΞυϨε৘ใऔಘ 
  6. int listener; for (server_addr_tmp = server_addr; server_addr_tmp; server_addr_tmp = server_addr_tmp->ai_next)

    { listener = socket(server_addr_tmp->ai_family, server_addr_tmp->ai_socktype, server_addr_tmp->ai_protocol); if (listener < 0) continue; if (bind(listener, server_addr_tmp->ai_addr, server_addr_tmp->ai_addrlen) < 0) { close(listener); continue; } break; } <$ͷ৔߹>αʔόʔΞυϨε৘ใऔಘ  ᶆϦΫΤετΛ଴ͪड͚ΔιέοτͷͨΊͷϝϞϦྖҬΛ༻ҙ ᶇΞυϨε৘ใΛ֨ೲ͢Δߏ଄ମ͕࣋ͭϦϯΫΛͨͲͬͯ ɹ͜ͷߏ଄ମͷҰ෦ͷ৘ใ͔ΒιέοτΛ࡞੒͠ɺ ɹߋʹ͜ͷߏ଄ମͷଞͷ৘ใ͔Β࣮ࡍʹΞυϨεͱόΠϯυͰ͖Δ͔ࢼΈΔ ᶈιέοτͷ࡞੒ͱΞυϨεͷόΠϯυʹ੒ޭͨ͠ΒιέοτΛฦ͢
  7. int listener; for (server_addr_tmp = server_addr; server_addr_tmp; server_addr_tmp = server_addr_tmp->ai_next)

    { listener = socket(server_addr_tmp->ai_family, server_addr_tmp->ai_socktype, server_addr_tmp->ai_protocol); if (listener < 0) continue; if (bind(listener, server_addr_tmp->ai_addr, server_addr_tmp->ai_addrlen) < 0) { close(listener); continue; } break; } <$ͷ৔߹>αʔόʔΞυϨε৘ใऔಘ  ᶆϦΫΤετΛ଴ͪड͚ΔιέοτͷͨΊͷϝϞϦྖҬΛ༻ҙ ᶇΞυϨε৘ใΛ֨ೲ͢Δߏ଄ମ͕࣋ͭϦϯΫΛͨͲͬͯ ɹ͜ͷߏ଄ମͷҰ෦ͷ৘ใ͔ΒιέοτΛ࡞੒͠ɺ ɹߋʹ͜ͷߏ଄ମͷଞͷ৘ใ͔Β࣮ࡍʹΞυϨεͱόΠϯυͰ͖Δ͔ࢼΈΔ ᶈιέοτͷ࡞੒ͱΞυϨεͷόΠϯυʹ੒ޭͨ͠ΒιέοτΛฦ͢ ➡︎ ೉͍͠ʜ ɹΞυϨεͷݕࡧͱιέοτͷ࡞੒Λಉ࣌ʹߦͬͯ ɹΞυϨεͷ༗ޮੑΛݕূ͢Δඞཁ͕͋Δ ޮ཰͕ѱ͍
  8. Addrinfo.getaddrinfo('localhost', 12345, Socket::AF_INET, Socket::SOCK_STREAM, nil, Socket::AI_PASSIVE). fi rst <3VCZͷ৔߹>αʔόʔΞυϨε৘ใऔಘ BEESJOGPSC

    ͜ͷॲཧΛΤίʔαʔόʔͷ಺෦Ͱ࣮ߦ͠ɺ ιέοτΛ࡞੒͢Δ ฦΓ஋ͱͳΔ"EESJOGPΦϒδΣΫτ ͷΞυϨε৘ใ Λར༻ͯ͠
  9. #include <mruby.h> #include “addrinfo.c” mrb_state *mrb = mrb_open(); // ͜͜Ͱ΍Δ͜ͱ

    // ɹɾBEESJOGP ؔ਺Λݺͼग़͢ // ɹɾ"EESJOGPΦϒδΣΫτ͔ΒΞυϨε৘ใΛऔಘ͢Δ // ɾɹऔಘͨ͠ΞυϨε৘ใͰιέοτΛ࡞੒͢Δ mrb_close(mrb); FDIPTFSWFSD BEESJOGPDΛಡΈࠐΉͱɺ BEESJOGP ؔ਺͕ར༻Ͱ͖ΔΑ͏ʹͳΔ 3VCZιʔείʔυΛΤίʔαʔόʔʹ૊ΈࠐΉ
  10. mrb_value addr = mrb_load_irep(mrb, addrinfo); mrb_value domain = mrb_funcall(mrb, addr,

    "afamily", 0); mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0); mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0); mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0); mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0); BEESJOGP ؔ਺Λݺͼग़͢ FDIPTFSWFSD BEESJOGP ؔ਺Λ࣮ߦ͢Δͱ"EESJOGPΦϒδΣΫτ͕ฦͬͯ͘Δ
  11. mrb_value addr = mrb_load_irep(mrb, addrinfo); mrb_value domain = mrb_funcall(mrb, addr,

    "afamily", 0); mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0); mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0); mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0); mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0); "EESJOGPΦϒδΣΫτ͔ΒΞυϨε৘ใΛऔಘ͢Δ ͜ͷ"EESJOGPΦϒδΣΫτ͔Β ιέοτͷ࡞੒ʹඞཁͳ֤छΞυϨε৘ใΦϒδΣΫτΛऔಘ͢Δ FDIPTFSWFSD υϝΠϯ໊ ιέοτλΠϓ ϓϩτίϧ ϙʔτ൪߸ *1ΞυϨε
  12. mrb_value addr = mrb_load_irep(mrb, addrinfo); mrb_value domain = mrb_funcall(mrb, addr,

    "afamily", 0); mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0); mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0); mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0); mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0); ֤ΞυϨε৘ใΦϒδΣΫτ͸͜ͷޙɺ ιέοτΛ࡞੒͢Δ$ؔ਺ͷҾ਺ͱͯ͠࢖༻͞ΕΔ ͦͷࡍ3VCZΦϒδΣΫτ͔Β$ͷJOUܕʹม׵͓ͯ͘͠ඞཁ͕͋Δ FDIPTFSWFSD "EESJOGPΦϒδΣΫτ͔ΒΞυϨε৘ใΛऔಘ͢Δ υϝΠϯ໊ ιέοτλΠϓ ϓϩτίϧ ϙʔτ൪߸ *1ΞυϨε
  13. mrb_value addr = mrb_load_irep(mrb, addrinfo); mrb_value domain = mrb_funcall(mrb, addr,

    "afamily", 0); mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0); mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0); mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0); mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0); FDIPTFSWFSD "EESJOGPΦϒδΣΫτ͔ΒΞυϨε৘ใΛऔಘ͢Δ υϝΠϯ໊ ιέοτλΠϓ ϓϩτίϧ ϙʔτ൪߸ ͜͜·Ͱ͸*OUFHFSΦϒδΣΫτ *OUFHFSΦϒδΣΫτ͸NSVCZͷ$"1*Λར༻͢Δ͜ͱͰ $ͷJOUܕ΁ม׵͢Δ͜ͱ͕Ͱ͖Δ
  14. "EESJOGPΦϒδΣΫτ͔ΒΞυϨε৘ใΛऔಘ͢Δ mrb_value addr = mrb_load_irep(mrb, addrinfo); mrb_value domain = mrb_funcall(mrb,

    addr, "afamily", 0); mrb_value socktype = mrb_funcall(mrb, addr, "socktype", 0); mrb_value protocol = mrb_funcall(mrb, addr, "protocol", 0); mrb_value port = mrb_funcall(mrb, addr, "ip_port", 0); mrb_value address = mrb_funcall(mrb, addr, "ip_address", 0); FDIPTFSWFSD 4USJOHΦϒδΣΫτ͸௚઀$ͷJOUܕ΁ม׵Ͱ͖ͳ͍ FHlz *1ΞυϨε͸4USJOHΦϒδΣΫτ ͋Β͔͡Ί4USJOHΦϒδΣΫτ͔Β*OUFHFSΦϒδΣΫτ΁ม׵͢Δඞཁ͋Γ
  15. *1ΞυϨε จࣈྻ Λ*1ΞυϨε ਺஋ ʹม׵͢Δ class Addr2Int RE_IPV4ADDRLIKE = %r{

    \A (\d+) \. (\d+) \. (\d+) \. (\d+) \z }x def self.convert(addr) m = RE_IPV4ADDRLIKE.match(addr) octets = m.captures octets.inject(0) { |i, s| (n = s.to_i) < 256 s.match(/\A0./) i << 8 | n } end end BEESJOUSC ࢀߟIUUQTHJUIVCDPNSVCZJQBEESCMPCDDCFBECDDGEMJCJQBEESSC- *1ΞυϨεͷจࣈྻΛ਺஋ʹม׵͢Δ "EES*OUDPOWFSUϝιουΛ༻ҙ *1"EESFTTϥΠϒϥϦͷUP@Jϝιουͷ࣮૷Λ͓आΓͯ͠ʜ
  16. "EESJOGPΦϒδΣΫτ͔ΒΞυϨε৘ใΛऔಘ͢Δ mrb_value addr = mrb_load_irep(mrb, addrinfo); // … mrb_value address

    = mrb_funcall(mrb, addr, "ip_address", 0); FILE *addr2int_src = fopen("addr2int.rb", "r"); mrb_load_ fi le(mrb, addr2int_src); fclose(addr2int_src); mrb_value addr2int_klass = mrb_obj_value(mrb_class_get(mrb, "Addr2Int")); mrb_value inaddr = mrb_funcall(mrb, addr2int_klass, "convert", 1, address); FDIPTFSWFSD BEESJOUSCιʔεϑΝΠϧΛ ಡΈࠐΉ "EES*OUDPOWFSUϝιουʹ*1ΞυϨε จࣈྻ Λ౉࣮ͯ͠ߦ
  17. "EESJOGPΦϒδΣΫτ͔ΒΞυϨε৘ใΛऔಘ͢Δ mrb_value addr = mrb_load_irep(mrb, addrinfo); // … mrb_value address

    = mrb_funcall(mrb, addr, "ip_address", 0); FILE *addr2int_src = fopen("addr2int.rb", "r"); mrb_load_ fi le(mrb, addr2int_src); fclose(addr2int_src); mrb_value addr2int_klass = mrb_obj_value(mrb_class_get(mrb, "Addr2Int")); mrb_value inaddr = mrb_funcall(mrb, addr2int_klass, "convert", 1, address); FDIPTFSWFSD ➡︎ *1ΞυϨεΛද͢*OUFHFSΦϒδΣΫτ͕ฦͬͯ͘Δ BEESJOUSCιʔεϑΝΠϧΛ ಡΈࠐΉ "EES*OUDPOWFSUϝιουʹ*1ΞυϨε จࣈྻ Λ౉࣮ͯ͠ߦ
  18. struct sockaddr_in saddr; saddr.sin_family = mrb_integer(domain); saddr.sin_addr.s_addr = htonl(mrb_integer(inaddr)); saddr.sin_port

    = htons(mrb_integer(port)); int listener; if ((listener = socket(mrb_integer(domain), mrb_integer(socktype), mrb_integer(protocol))) < 0) { perror("socket(2)"); exit(1); } // … औಘͨ͠ΞυϨε৘ใͰιέοτΛ࡞੒͢Δ FDIPTFSWFSD ΞυϨε৘ใͷ*OUFHFSΦϒδΣΫτΛ$ͷJOUܕʹม׵͠ɺ ιέοτΛ࡞੒ ҎԼɺͦͷଞͷॲཧΛ࣮૷ ม׵ ιέοτ࡞੒ ม׵ ม׵ ม׵ ม׵ ม׵