- ベストアンサー
PerlのPerlgutsで構造体の受け渡しについて
- Perlgutsを使用してPerlで構造体の受け渡しを行いたいが、二度目にDataListを通すとバラバラな構造体が生成される。
- 生成される構造体を同じにするにはどうしたら良いか教えてください。
- 質問者の環境はWindows 7です。
- みんなの回答 (3)
- 専門家の回答
質問者が選んだベストアンサー
提案させていただいた#1,#2の$value1引数は取り下げます。 決定的にまずいところがありました。 sizeof(struct tfield) = 276 sizeof(struct tfield *) = 4 struct tfield *p,*head[30];→head[30]でないとメモリに収まりません。 メモリの割当ですが、以下のようにするようです。Perlが機能を提供しています。 http://argrath.ub32.org/perldocjp/5.10.0/perlguts.html#memory_allocation Newx(pointer, number, type); Newxc(pointer, number, type, cast); Newxz(pointer, number, type); (これだけは獲得した領域を0で埋める) ケーススタディが多くてXS/Perlgutsの日本語資料はなかなかあたれませんね。
その他の回答 (2)
- hirotn
- ベストアンサー率59% (147/246)
No.1でジャストアイデアで書いてしまいましたが。(申し訳ありません) 原因がMyListへ構造体のポインタが渡っていないことが原因であれば、 $value1=MyType::DataList($$value1,1); の方が適切のように思えました。 \$value1の場合、$value1のアドレスを示し(Cの&相当) $$value1の場合、$value1に格納されたアドレスを参照します(Cの*相当) 図のような関係になります。 直ちに再現できず、dumpからの提案となりますが、参考になれば幸いです。 URLはPerlにおけるポインタの情報です。
補足
返答遅れてすいません。 と、いうのもですね。実はまだ解決できてないんです。 DataListに$value1を渡して再度アクセスし $value1と仮定してSvSTASH(SvRV(data))や $$value1と仮定してSvSTASH(data)や色々と アプローチを試みましたが、正しい応え得られませんでした。 再度DataListにアクセすると、上記の例なら STASH = 0x12089bc "main::Tie"から 一バイトずつスタック領域を閲覧する構造体なら得られます。 これはひょっとして、Windows環境だから一回目のDataListを抜けた後、スタック領域が開放されてるいる可能性が有ります。 Perlguts全般は海外でもソースが少なくとても 有益な情報だと思います。下記URLは http://cpansearch.perl.org/src/RURBAN/illguts-0.35/index.html#svrv-8 SvPVMG構造体の予備知識の様な物です。参考URLとリンクします
- hirotn
- ベストアンサー率59% (147/246)
$value1=MyType::DataList($value1,1); を、 $value1=MyType::DataList(\$value1,1); とした場合どうでしょう SV = IV(0x1209078) at 0x120907cとあるので、現状は、0x1209078が渡っているのを、\$value1とし、リファレンスとすることで、$value1そのもののアドレス0x120907cを渡すようにできないかというアイデアですが、参考になれば幸いです。 以下のサイトを参考にしてみてください。 http://blog.64p.org/entry/20120326/1332757819
補足
参考URLとてもためになる内容でした。 色々とアプローチを試みましたが、問題解決には至りませんでした。
お礼
struct tfield **headで宣言し ↓ここを ------------------------------- for(i=0;i<6;i++){ /*無意味な構造体*/ head[i]->left[0]=head[i]->right[0]=head[i]=talloc(); printf("head[0]->left[%d]=%p\n",i,&head[0]->left[i]); } ------------------------------- ここに for(i=0;i<6;i++){ Newx(head,276,struct tfield*); Newx(head[i],4,struct tfield); printf("head[%d]->left[0]=%p\n",i,&head[i]->left[0]); } ------------------------------- 差し替えたら上手くいきました。 これが非常に参考になりました。 >sizeof(struct tfield) = 276 >sizeof(struct tfield *) = 4 > >struct tfield *p,*head[30];→head[30]でないとメモリに>収まりません。 ちなみに、もしよろしかったら sizeof(struct tfield) = 276 なぜ276になるのか、参考までに聞きたいんですが。 ここまでに費やした時間は一ヶ月は掛かりました。 参考URL: http://perldoc.jp/docs/perl/5.14.1/perlguts.pod http://perldoc.jp/docs/perl/5.8.8/perlxs.pod http://d.hatena.ne.jp/ksmemo/20081221/p2 http://webcache.googleusercontent.com/search?q=cache:r3wTvquG5M0J:d.hatena.ne.jp/unau/20100127/1264555111+Perl+PVMG&cd=2&hl=ja&ct=clnk&gl=jp&lr=lang_ja http://d.hatena.ne.jp/hiratara/20080625/1214389654 http://www.gadgety.net/shin/tips/unix/perl.html http://webcache.googleusercontent.com/search?q=cache:gHClOI99o7gJ:www.perlmonks.org/%3Fnode_id%3D894139+Perl+%22Newx%22&cd=4&hl=ja&ct=clnk&gl=jp 動画: http://www.nicovideo.jp/watch/sm8619094?via=thumb_watch 目を通した所 http://webcache.googleusercontent.com/search?q=cache:2N3D9rH1ahAJ:perl.g.hatena.ne.jp/bosh/20090809+Perl+mg_find&cd=2&hl=ja&ct=clnk&gl=jp http://perldoc.jp/docs/perl/5.14.1/perlcall.pod http://d.hatena.ne.jp/perlcodesample/20100824/1278596435 http://d.hatena.ne.jp/syohex/20110929/1317308531 http://webcache.googleusercontent.com/search?q=cache:UYBHOxwfedEJ:d.hatena.ne.jp/gfx/20090627/1246087813+Perl+HV*+%E5%8F%82%E7%85%A7&cd=11&hl=ja&ct=clnk&gl=jp http://webcache.googleusercontent.com/search?q=cache:_5o3ifh1WMcJ:perldoc.jp/docs/perl/5.6.1/perldiag.pod+Can't+coerce+HASH+to+integer+in+subroutine+entry+at&cd=1&hl=ja&ct=clnk&gl=jp&lr=lang_ja http://webcache.googleusercontent.com/search?q=cache:urAp6fFxifoJ:en.sourceforge.jp/projects/perldocjp/lists/archive/cvs/2012-August/001522.html+sv_magic&cd=15&hl=ja&ct=clnk&gl=jp&lr=lang_ja http://d.hatena.ne.jp/gfx/20090204/1233725975 http://cpansearch.perl.org/src/RURBAN/illguts-0.35/index.html#svpv http://webcache.googleusercontent.com/