perlapi - XSã«ããããã¼ã¿æä½é¢æ°
perlapiã¨ã¯XSã§Perlã®ãã¼ã¿ãæä½ããããã®å ¬å¼APIã§ãCè¨èªã§æ¸ããããã¯ããé¢æ°ã®ãã¨ã§ãã
åºåãã¹ã«ã©ãæ¨æºå ¥åºå
Perlã¨XS(Cè¨èª)ã®APIã®å¯¾å¿ããããã¨XSããããããããã ã
æ¨æºåºåã¸ã®åºå
#Perl print "Hello"; # XS PerlIO_printf(PerlIO_stdout(), "Hello");
PerlIO_printfã¯Cæ¨æºã©ã¤ãã©ãªã®printfã«ãããé¢æ°ã第ä¸å¼æ°ã¯PerlIO*åã®å¤æ°ã第äºå¼æ°ã¯char*åã®å¤æ°ãæ¨æºåºåã¯PerlIO_stdouté¢æ°ã§åå¾ã§ãããXSã§ã¯æ¨æºå ¥åºåCã®æ¨æºã©ã¤ãã©ãªã¯ä½¿ããã«ãPerlã§ç¨æããã¦ããé¢æ°ã使ããããã¯perlapioã¨ããããã¥ã¡ã³ãã«è©³ããä¹ãããã¦ããã
æåå
#Perl my $str = "Hello"; # XS SV* sv_str = newSVpv("Hello", 0);
Perlã®ã¹ã«ã©ã¯XSã§ã¯SV*ã«å¯¾å¿ãã¾ããnewSVpvé¢æ°ã§文字列ã表ç¾ããSV*ãä½æãããã¨ãã§ãã¾ãã第ä¸å¼æ°ã¯ãæååã§ãã第äºå¼æ°ã¯STRLENåã®å¼æ°ã§ãæååã®é·ããæå®ãã¾ãã0ãæå®ããã¨èªåçã«æååã®é·ãã決å®ãã¦ããã¾ãã
ãã®ä»ã®ãã®ã¨ãã¦ãå¹çãéè¦ãããnewSVpvné¢æ°ãnewSVpvsé¢æ°ãããã¾ãã
Cè¨èªã®APIã¯çç¥ãå¤ãã®ã§è¦ããã®ã大å¤ã§ãããæ £ããã¾ã§ããã°ããããªãã§ããSVã®Sã¯ã¹ã«ã©ã¨ããæå³ãVã¯å¤(value)ã¨ããæå³ã§ããnewSVpvã®pã¯ãã¤ã³ã¿(pointer)ã¨ããæå³ã§ããããã¯å®è³ªçã«ã¯æååã表ãã¾ããã§ãããpã¯æååã¨è¦ãã¾ãã
æ°å¤
# 符å·ãªãæ´æ° # Perl my $num = 1; #XS SV* sv_num = newSVuv(5);
# æ´æ° # Perl my $num = -1; #XS SV* sv_num = newSViv(-1);
# æ°å¤ # Perl my $num = 1.14; #XS SV* sv_num = newSVnv(1.14);
Perlã§ã¯数値ã¯ãã¹ã¦ã©ã®ãããªãã®ã§ãæµ®åå°æ°ç¹ã¨ãã¦æ±ããã¾ãããå é¨çã«è¦ãã¨ç¬¦å·ãªãæ´æ°(UVå)ãæ´æ°(IVå)ãæ°å¤å(NVå)ã®ä¸ç¨®é¡ããããæ°å¤åãæãæ±ç¨æ§ãããããå¹çã¯ç¬¦å·ãªãæ´æ°ãæ´æ°ã®ã»ããããããããã¯SV*ã®å é¨çãªå¤ã¨ãã¦ä¿æããã¾ããUVã®Uã¯ãunsigned intãã®uã§ããIVã®Iã¯intã®iã§ããNVã®Nã¯numberã®nã§ãã
æªå®ç¾©å¤(undefã«å¯¾å¿)
XSã§ã¯Perlã®undefã¯ã&PL_sv_undefã§è¡¨ç¾ãã¾ãã
# Perl my $val = undef; # XS SV* sv_val = &PL_sv_undef;
å¤ãå®ç¾©ããã¦ãããã©ããã®ãã§ãã¯(definedé¢æ°ã«å¯¾å¿)
SV*åã®å¤ãå®ç¾©ããã¦ãããã©ããã確èªããã«ã¯ãSvOKé¢æ°ã使ç¨ãã¾ããããã¯Perlã®defined関数ç¸å½ã®ãã¨ããã¾ãã
# Perl if (defined $val) { ... } # XS if (SvOK(sv_val)) { ... }
SV*ããchar*åã¸ã®å¤æ
SV*ã«æååãæ°å¤ãå«ã¾ãã¦ããå ´åã¯ãããä»ã®é¢æ°ãªã©ã§ä½¿ãå ´åã«ãchar*åã«ããå¿ è¦ãããã¾ãã
char* str = SvPV_nolen(sv_some);
SvPV_nolené¢æ°ã®ç¬¬ä¸å¼æ°ã¯SV*åã®å¤æ°ã§ããé·ãã«ã¤ãã¦ã¯èªåçã«è¨ç®ãã¦ããã¾ãã
ãã¡ã¤ã«å ¥åºå
#Perl sub print_line { my $file = shift; open my $fh, '<', $file or die $!; while (my $line = <$fh>) { print $line; } close $fh; } #XS SV* print_line(...) PPCODE: { char* file = SvPV_nolen(ST(0)); PerlIO* infh = PerlIO_open(file, "r"); SV* line = sv_2mortal(newSVpv("", 0)); if (!infh) { croak(strerror(errno)); } while(sv_gets(line, infh, 0)) { PerlIO_printf(PerlIO_stdout(), SvPV_nolen(line)); } PerlIO_close(infh); }
é£ããããã¡ã¤ã«å ¥åºåã£ã¦ããã§ãã£ã¦ããã®ããªãã
SV*ã¯æ®çºæ§ã«ãã¦ãã
SV*ãä½æããã¨ãã¯å¿ ãsv_2mortalãã¦æ®çºæ§ã«ãã¦ãããããããã¨ã¹ã³ã¼ããæããä½ç½®ã§èªåçã«è§£æ¾ãããã
XSã§ã¡ã¢ãªãªã¼ã¯ãããªãããã«ããè¨è¿°æ¹æ³ã¯ä»¥ä¸ã§è§£èª¬ãã¦ãã¾ãã
Perlã§ã®æä½ã«å¯¾å¿ããAPIãçºè¦ãã
XSãæ¸ãããã«ã¯ãã¤ãã¯Perlã§è¡ã£ã¦ããæä½ãCè¨èªã®APIã§è¡ãå¿ è¦ããããããã¯ãªããªã大å¤ã ããperlapiã¨perlapioã«å ¬éããã¦ããAPIããã¹ã¦è¼ã£ã¦ããã®ã§ããããæ¢ããPerlã®å é¨ã解説ããperlgutsãåèã«ãªãã
é åæä½
配列ã®æä½ã«å¯¾å¿ããXSã§ã®æ¸ãæ¹ã
å¤æ°å®£è¨ã
# Perl my @nums; # XS AV* av_nums = newAV();
ä»£å ¥ã
# Perl $nums[0] = 1; # XS av_store(av_nums, 0, newSVuv(1));
è¦ç´ ã®åå¾ãav_fetchã¯SV*ã¸ã®ãã¤ã³ã¿ãè¿ãã®ã§*ã§ãã¤ã³ã¿ã¯ãããè¡ãå¿ è¦ãããã¾ãã第ä¸å¼æ°ã¯è¦ç´ ãåå¨ããªãã£ãå ´åã«ä½æãããã©ãããæå®ãã¾ããav_fetchã¯è¦ç´ ããªãã£ãå ´åã«NULLãè¿ãã®ã§ç¢ºèªãã¦ããåç §ã¯ãããè¡ãå¿ è¦ãããã¾ãã
# Perl my $num = $nums[0]; # XS SV** const sv_num_ptr = av_fetch(nums, 0, FALSE); SV* const sv_num = num_ptr ? *sv_num_ptr : &PL_sv_undef;
é åã®ãµã¤ãºã
# Perl my $count = @nums; # XS(æ´å²çäºæ ã§é·ããã1å°ããå¤ãè¿ã£ã¦ããã®ã§æ³¨æ) int count = av_len(nums) + 1;
pushé¢æ°ã
# Perl push @nums, 1; # XS av_push(av_nums, newSVuv(1));
popé¢æ°ã
# Perl my $num = pop @nums; # XS SV* sv_num = av_pop(av_nums);
shifté¢æ°ã
# Perl my $num = shift @nums; # XS SV* sv_num = av_shift(av_nums);
unshifté¢æ°ãav_unshiftã¯å¤ãå é ã«ã¤ãå ããã®ã§ã¯ãªããå é ã«ç©ºã®é åã追å ããã ããªã®ã§ãav_storeã§å¤ãè¨å®ããå¿ è¦ãããã¾ãã
# Perl unshift @nums, 1; # XS av_unshift(av_nums, 1); av_store(av_nums, 0, newSVuv(1));
é åã空ã«ã
# Perl @nums = (); # XS av_clear(av_nums);
ããã·ã¥æä½
ハッシュã®æä½ã«å¯¾å¿ããXSã§ã®æ¸ãæ¹ã
ãã¼ã®åå¨ç¢ºèª
# Perl exists $hash{"key"}; # XS hv_exists(hash, "key", strlen("key"));
ããã·ã¥ã®é åã®ä½æ
XSãæè¿ç·´ç¿ãã¦ãã¦ãã¨ãããã次ã®æ¹éã§ä½æãã¦ãããããã£ã¦ãããã¯ããããããªãã
- æ»ãå¤ã¨å¼æ°ã¯ä¸è¡ã§æ¸ãã¦ãã¾ã
- PPCODEã»ã¯ã·ã§ã³ã®ã¿ã使ãã
- ã½ã¼ã¹ã³ã¼ãã¯å é ã§å¤æ°å®£è¨ãã§ããããã« {} ã§å²ã
- æ»ãå¤ã¯SV*ã²ã¨ã¤ã ãã«ãããST(0)ã«ä»£å ¥ãã¦ãããXSRETURN(1)ãRETVALã使ã£ã¦ããªãã¨ããè¦åã¯ç¡è¦ããã
- SV*ãAV*ãHV*ã¯ä½æããç´å¾ã«sv_2mortalãå®è¡ããããããè¡ããªãã¨ã¡ã¢ãªãªã¼ã¯ãçºçãã¾ããSV*ãä½æãã¦sv_2mortalããªãã¦ããã®ã¯ããã·ã¥ãé åã®è¦ç´ ã«ããå ´åã®ã¿ã
XSãæ¸ãã¨ãã«ãã°ããããããæ¸ãæ¹ããã¦ã¿ããã¨ã«ãããXSã®ææ³ã¯ããªãè¤éãªã®ã§ã§ããã ãã·ã³ãã«ãã¤ä¸è²«æ§ã®ããæ¸ãæ¹ãããããããã§ã©ããããã®å ´åã«ãã¾ããããããã°ãã試ãã¦ã¿ãã
ããã·ã¥ã®é åã®ä½æ
ããã·ã¥ã®é åã®ä½æã§ãã
# æãã·ã³ãã«ãªPerlè¨æ³ sub return_array_of_hash { my $persons = [ {name => 'Ken', age => 19}, {name => 'Taro', age => 16} ]; return $persons; } # XSã®æ¸ãæ¹å¯¾å¿ãããPerlè¨æ³ sub return_array_of_hash { my @persons; my %person1; $person1{name} = 'Ken'; $person1{age} = 19; push @persons, \%person1; my %person2; $person2{name} = 'Taro'; $person2{age} = 26; push @persons, \%person2; return \@persons; } # XS SV* return_array_of_hash() PPCODE: { AV* av_persons; HV* hv_person1; HV* hv_person2; av_persons = (AV*)sv_2mortal((SV*)newAV()); hv_person1 = (HV*)sv_2mortal((SV*)newHV()); hv_store(hv_person1, "name", 4, newSVpv("Ken", 3), 0); hv_store(hv_person1, "age", 3, newSVuv(19), 0); av_push(av_persons, newRV_inc((SV*)hv_person1)); hv_person2 = (HV*)sv_2mortal((SV*)newHV()); hv_store(hv_person2, "name", 4, newSVpv("Taro", 4), 0); hv_store(hv_person2, "age", 3, newSVuv(26), 0); av_push(av_persons, newRV_inc((SV*)hv_person2)); SV* sv_ret = sv_2mortal(newRV_inc(av_persons)); xPUSHs(sv_ret); XSRETURN(1); }
AV*ã¯é åãHV*ã¯ããã·ã¥ãnewAVã¯ç©ºã®é åã®ä½æãnewHVã¯ç©ºã®ããã·ã¥ã®ä½æãhv_storeã¯ããã·ã¥ã®å¤ã®è¨å®ã第ä¸å¼æ°ã¯ãã¼ã®é·ãã第5å¼æ°ã¯0ãæå®ããã¨ããã·ã¥å¤ãèªåã§è¨ç®ããããnewRV_incã¯ãªãã¡ã¬ã³ã¹ãä½æããé¢æ°ãXSRETURNã®å¼æ°ã¯æ»ãå¤ã®åæ°ãæ»ãå¤ã¯XPUSHsãã¯ãã§ã¹ã¿ãã¯ã«ç©ãã
ããã·ã¥ã®é åã®ä½æãã®2
gfxããã®ã¢ããã¤ã¹ãå ã«ãã¦ããã·ã¥ã®é åã®ä½æãæ¸ãç´ãã¦ã¿ã¾ãããSV*,AV*,HV*ãä½ã£ãç´å¾ã«å¿ ãmortalã«ããã¨ããååãæååãä½æããã¨ããããã·ã¥ã®è¦ç´ ãè¨å®ããã¨ãã«æåæ°ãæå®ããªãããã«ãããã¨ãé åãããã·ã¥ã®è¦ç´ ã«ããã¨ãã¯ãªãã¡ã¬ã³ã¹ã«ã¦ã³ããã²ã¨ã¤å¢ãããªãã¨ãããªããã¨ããã¨ã¯ã§ããã ãä¸è²«ãã¦ã·ã³ãã«ã«æ¸ããã¨ãã§ãããããªãã¯ããå®ç¾©ãã¦ã¿ã¾ãããã©ãããªãã
#define new_mAV() (AV*)sv_2mortal((SV*)newAV()) #define new_mHV() (HV*)sv_2mortal((SV*)newHV()) #define new_mSVpvs(s) sv_2mortal(newSVpvs(s)) #define new_mSVuv(u) sv_2mortal(newSVuv(u)) #define new_mSViv(i) sv_2mortal(newSViv(i)) #define new_mSVnv(n) sv_2mortal(newSVnv(n)) #define new_mRV(sv) sv_2mortal(newRV_inc((SV*)sv)) #define set(e) SvREFCNT_inc(e) MODULE = ExtModule PACKAGE = ExtModule SV* return_array_of_hash() PPCODE: { AV* persons; HV* person1; HV* person2; persons = new_mAV(); person1 =new_mHV(); hv_stores(person1, "name", set(new_mSVpvs("Ken"))); hv_stores(person1, "age", set(new_mSVuv(19))); hv_stores(person1, "height", set(new_mSViv(170))); hv_stores(person1, "weight", set(new_mSVnv(45.3))); av_push(persons, set(new_mRV(person1))); person2 = new_mHV(); hv_stores(person2, "name", set(new_mSVpvs("Taro"))); hv_stores(person2, "age", set(new_mSVuv(26))); hv_stores(person2, "height", set(new_mSViv(180))); hv_stores(person2, "weight", set(new_mSVnv(39.3))); av_push(persons, set(new_mRV(person2))); ST(0) = new_mRV(persons); XSRETURN(1); }
æååæä½
XSã«ããã文字列æä½ã§ãã
æååã®ä½æ
# Perl my $str = "abc"; # XS SV* sv_str = newSVpv("abc", 0);
æååã®ã³ãã¼
# Perl my $str2 = $str1; # XS SV* sv_str2 = newSV(sv_str1);
æååã®é·ã
# Perl my $length = length $str; # XS STRLEN sv_length = sv_len(sv_str);
æååã®é£çµ
# Perl my $str = "abc"; $str .= "de"; # XS SV* sv_str = newSVpv("abc", 0); sv_catpv(sv_str, "de");
å¤æ°å±é(ãããã¯sprintf)
# Perl my $num1 = 1; my $num2 = 2; my $str = "$num1 and $num2"; # XS int num1 = 1; int num2 = 2; SV* sv_str = newSVpvf("%d and %d", num1, num2);
æååã®é£çµ+å¤æ°å±é
# Perl my $num1 = 1; my $num2 = 2; my $str = "abc"; $str .= "$num1 and $num2"; # XS int num1 = 1; int num2 = 2; SV* sv_str = newSVpv("abc", 0); sv_catpvf(sv_str, "%d and %d", num1, num2);
æååã®æ¯è¼
SVã§ããæååãæ¯è¼ãããå ´åã¯sv_cmpã使ç¨ãã¾ãã
# perl if ($str1 lt $str2) { ... } if ($str1 eq $str2) { ... } if ($str1 gt $str2) { ... } # XS if (sv_cmp(sv_str1, sv_str2) < 0) { ... } if (sv_cmp(sv_str1, sv_str2) == 0) { ... } if (sv_cmp(sv_str1, sv_str2) > 0) { ... }
ã¾ãchar*åã¨ãã¦æ¯è¼ã§ããé¢æ°strEQ, strEQ, strGE, strGT, strLE, strLT, strNEãç¨æããã¦ãã¾ãã
if (strEQ("foo", "bar")) { ... } if (strGE("foo", "bar")) { ... } if (strGT("foo", "bar")) { ... } if (strLE("foo", "bar")) { ... } if (strLT("foo", "bar")) { ... } if (strNE("foo", "bar")) { ... }
ããã±ã¼ã¸å¤æ°
XSã«ãããããã±ã¼ã¸å¤æ°ã®æä½ã®ããã®é¢æ°ãç´¹ä»ãã¾ãã
ããã±ã¼ã¸å¤æ°ã®åå¾
ããã±ã¼ã¸å¤æ°ãåå¾ããã«ã¯æ¬¡ã®ããã«æ¸ãã¾ãã
# Perl $Foo::bar; @Foo::bar; %Foo::bar; # XS SV* sv_var = get_sv("Foo::bar", 0); AV* av_var = get_av("Foo::bar", 0); HV* hv_var = get_hv("Foo::bar", 0);
第äºå¼æ°ã®0ã¯æ°ããå¤æ°ãä½æããªããã¨ãæå³ãã¾ãã
ããã±ã¼ã¸å¤æ°ã®ä½æ]
XSã§ããã±ã¼ã¸å¤æ°ãä½æããé¢æ°ãç´¹ä»ãã¾ããget_sv, get_av, get_hvã®ç¬¬äºå¼æ°ã§ãGV_ADDããæå®ãã¾ãã
# Perl our $Foo::bar; our @Foo::bar; our %Foo::bar; # XS SV* sv_var = get_sv("Foo::bar", GV_ADD); AV* av_var = get_av("Foo::bar", GV_ADD); HV* hv_var = get_hv("Foo::bar", GV_ADD);
æ£è¦è¡¨ç¾ãå©ç¨ãã
XSã§正規表現ã使ãæ¹æ³ã解説ãã¾ãããã ããç¾å¨ãPerlã®ããã¥ã¡ã³ãã«ä½¿ç¨æ¹æ³ã解説ããã¦ããªãã®ã§ã試ã試ãã§ãã£ã¦ããã®ã§ãééã£ã¦ãããæãã¦ãã ããã
æ£è¦è¡¨ç¾ã®ã³ã³ãã¤ã«
XSã§正規表現ã使ç¨ããã«ã¯ã¾ãpregcompé¢æ°ã使ã£ã¦ãæ£è¦è¡¨ç¾ãã³ã³ãã¤ã«ããå¿ è¦ãããã¾ããããã¯ãæ£è¦è¡¨ç¾ã®ãªãã¡ã¬ã³ã¹ãä½æããæä½ã«å¯¾å¿ããã¨èãã¦ãã ããã
# Perl my $re = qr/[0-9]+/; # XS (pregcompã®ç¬¬äºå¼æ°ã¯æ£è¦è¡¨ç¾ã®ãã©ã°) SV* sv_re_str = newSVpv("[0-9]+", 0); REGEXP* sv_re = pregcomp(sv_re_str, 0);
REGEXP*åã¯ãSV*åã®ä¸ç¨®ã§ãã®ã§ãå®éã«ã³ã¼ããå©ç¨ããã¨ãã¯sv_2mortalã使ã£ã¦ãèªåçã«ã¡ã¢ãªã解æ¾ãããããã«ãã¾ããããå®éã®ã³ã¼ãã§å©ç¨ããã®ãæ³å®ãã¦æ¸ãã¨æ¬¡ã®ããã«ãªãã¾ãã
SV* sv_re_str = sv_2mortal(newSVpv("[0-9]+", 0)); REGEXP* sv_re = (REGEXP*)sv_2mortal((SV*)pregcomp(sv_re_str, 0));
æ£è¦è¡¨ç¾ã®ãã©ã°
æ£è¦è¡¨ç¾ã®ãã©ã°ããpregcompã®ç¬¬äºå¼æ°ã«æå®ãããã¨ãã§ãã¾ãã
# Perl my $re = qr/abc/im; # XS SV* sv_re_str = newSVpv("[0-9]+", 0); REGEXP* sv_re = pregcomp(sv_re_str, RXf_PMf_FOLD | RXf_PMf_MULTILINE);
ãã©ã°ã®å¯¾å¿ã¯ä»¥ä¸ã§ããè¤æ°æå®ããå ´åã¯ãããæ¼ç®åã®è«çåã|ãã§ããã©ã°ãã¤ãªãã¾ãã
/m | RXf_PMf_MULTILINE | |
/s | RXf_PMf_SINGLELINE | |
/i | RXf_PMf_FOLD | |
/x | RXf_PMf_EXTENDED |
æ£è¦è¡¨ç¾ã®å®è¡
æ£è¦è¡¨ç¾ãå®è¡ããã«ã¯pregexecé¢æ°ã使ç¨ãã¾ããpregexecé¢æ°ã®å¼æ°ã¯ãã¨ã¦ãè¤éã§ãã
/* pregexec - æååã«å¯¾ãã¦æ£è¦è¡¨ç¾ãããããããã */ I32 pregexec( REGEXP * const prog, /* ã³ã³ãã¤ã«ãããæ£è¦è¡¨ç¾ */ char* stringarg, /* æååã®ããããéå§ããä½ç½® */ char *strend, /* æååã®çµç«¯(NULLãã¤ã³ã¿ã®ä½ç½®) */ char *strbeg, /* æååã®éå§ä½ç½® */ SSize_t minend, /* stringargå¾ã®ãããã®çµç«¯ãminend以ä¸ã§ãªããã°ãªããªããã¤ãæ° */ SV *screamer, /* æååãããããSV: utf8ãã©ã°ã®ããã ãã«å©ç¨ããã */ U32 nosave /* ãã£ããã£ããªãå ´åã¯1ãè¨å® */ )
ããããæåããå ´åã¯æ»ãå¤ã«çãè¿ãã¾ãããµã³ãã«ãè¨è¿°ãã¦ããã¾ãã
SV* sv_value = sv_2mortal(newSVpv(" 12", 0)); char* value = SvPV_nolen(sv_value); SV* sv_re_str = sv_2mortal(newSVpv("^ *([-+]?[0-9]+) *$", 0)); REGEXP* sv_re = (REGEXP*)sv_2mortal((SV*)pregcomp(sv_re_str, 0)); IV ret = pregexec( sv_re, // ã³ã³ãã¤ã«ãããæ£è¦è¡¨ç¾ value, // æ¤ç´¢éå§ä½ç½® value + strlen(value), // æååã®çµç«¯(NULLãã¤ã³ã¿) value, // æååã®é 0, // 0ã§OK sv_value, // SV*åã®æåå 0 // 0ã§OK );
ãããããæååã®åå¾
ãããããæååãåå¾ããã«ã¯Perl_reg_numbered_buff_fetché¢æ°ã使ç¨ãã¾ãã(éå ¬éã®APIãããªãã®ããª)
# Perl my $match1 = $1; my $match2 = $2; # XS SV* sv_match1 = newSVpv("", 0); Perl_reg_numbered_buff_fetch(aTHX_ sv_re, 1, match1); SV* sv_match2 = newSVpv("", 0); Perl_reg_numbered_buff_fetch(aTHX_ sv_re, 2, match2);
ãªãã¸ã§ã¯ãæåé¢é£ã®API
オブジェクト指向ã«é¢é£ããXSã®APIãç´¹ä»ãã¾ãã
ãªãã¸ã§ã¯ããçæãã
ãªãã¸ã§ã¯ããçæãã¾ããå¿ ãã¢ã¼ã¿ã«ã«ãã¦ããã¾ãããã
# Perl my $self = {}; bless $self, "MyClass"; # XS SV* sv_self = sv_2mortal(new_RV_inc(sv_2mortal((SV*)newHV())); sv_bless(sv_self, gv_stashpv("MyClass", 1));
ãªãã¸ã§ã¯ãã§ãããã©ããã確èªãã
å¤ããªãã¸ã§ã¯ãã§ãããã©ããã確èªããã«ã¯ãsv_isobjecté¢æ°ã使ç¨ãã¾ãã
sv_isobject(sv_obj);
ããã¯ã©ã¹ãç¶æ¿ãã¦ãããã©ããã確èªãã
ããã¯ã©ã¹ãç¶æ¿ãã¦ãããã©ããã確èªããã«ã¯sv_derived_fromé¢æ°ã使ç¨ãã¾ããæå®ããã¯ã©ã¹ãç¶æ¿ãã¦ããå ´åã¯ãçãè¿ã£ã¦ãã¾ãã
sv_derived_from(sv_obj, "MyClass");
ãã®é¢æ°ã¯ãé åã®ãªãã¡ã¬ã³ã¹ã§ãããã¨ããããã·ã¥ã®ãªãã¡ã¬ã³ã¹ã§ãããã¨ã確èªããã®ã«å©ç¨ãããã¨ãå¯è½ã§ãã
/* é åã®ãªãã¡ã¬ã³ã¹ */ sv_derived_from(sv_obj, "ARRAY"); /* ããã·ã¥ã®ãªãã¡ã¬ã³ã¹ */ sv_derived_from(sv_obj, "HASH");
ã§ãã®ã§ããªãã¸ã§ã¯ãã§ãããç¹å®ã®ã¯ã©ã¹ãç¶æ¿ãã¦ãããã¨ã確èªããã«ã¯ãsv_isobjecté¢æ°ã¨sv_derived_fromé¢æ°ãçµã¿åããã¦å©ç¨ãã¾ãã
sv_isobject(sv_obj) && sv_derived_from(sv_obj, "MyClass")
Perl APIã®å ¬å¼ããã¥ã¡ã³ã
- perlguts - Perl API の紹介 - Perlã®å é¨ãã¼ã¿æ§é ã¨APIã®ç´¹ä»ã«ã¤ãã¦æ¸ããã¦ãã¾ãã
- perlapi - perl public API の自動生成ドキュメント - Perlã®APIã®ä¸è¦§ãæ²è¼ããã¦ãã¾ãã