Hoge*なtfield型の
*head構造体を生成してPerl側で参照し、
再度同じ関数に通して*headと同じ構造体*pを作りたい。
下記のソースを
実行すると二度目にDataListを通すと
tfield *pはバラバラな構造体が生成される。
*headと同じ構造体が
生成されるにはどうしたら良いか。
ご教授お願いします。m(_ _)m
ちなみに使用環境はWindow7です。
-----------------------------------------
MyTpe.xs側
struct tfield {
struct tfield *left[30];
int num;
char str[30];
struct tfield *right[30];
};
struct tfield *talloc(void)
{
return ((struct tfield *)malloc(sizeof(struct tfield )));
}
MODULE = MyTypePACKAGE = MyType
SV*
DataList(data,num)
SV* data
int num
PREINIT:
struct tfield *p,*head[30];
INIT:
int i,j;
CODE:
if(num!=0){
p=INT2PTR(struct tfield *,SvSTASH(SvRV(data)));
f(SvTYPE(SvRV(data))==SVt_PVMG)
printf("MG Success\n");
or(i=0;i<6;i++){
printf("\np->left[%d]=%p\n",i,p->left[i]);
}
}
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]);
}
ref=newRV_noinc(newHV());
sv_setref_pv(ref,"main::Tie",(void*)head);
RETVAL=ref;
OUTPUT:
RETVAL
-----------------------------------------
Perl側
#!usr/bin/perl
use MyType;
use Devel::Peek qw/Dump/;
$value1=MyType::DataList(NULL,0);
print Dump $value1;
$DB::single=1;
$value1=MyType::DataList($value1,1);
-----------------------------------------
Devel::Peekの実行結果
SV = IV(0x1209078) at 0x120907c
REFCNT = 1
FLAGS = (ROK)
RV = 0x5bbbcc
SV = PVMG(0x18cf78c) at 0x5bbbcc
REFCNT = 1
FLAGS = (OBJECT,IOK,pIOK)
IV = 1243644
NV = 0
PV = 0
STASH = 0x12089bc "main::Tie"
No.1
- 回答日時:
$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
No.2
- 回答日時:
No.1でジャストアイデアで書いてしまいましたが。
(申し訳ありません)原因がMyListへ構造体のポインタが渡っていないことが原因であれば、
$value1=MyType::DataList($$value1,1);
の方が適切のように思えました。
\$value1の場合、$value1のアドレスを示し(Cの&相当)
$$value1の場合、$value1に格納されたアドレスを参照します(Cの*相当)
図のような関係になります。
直ちに再現できず、dumpからの提案となりますが、参考になれば幸いです。
URLはPerlにおけるポインタの情報です。
参考URL:http://www.geocities.co.jp/SiliconValley-Sunnyva …
この回答への補足
返答遅れてすいません。
と、いうのもですね。実はまだ解決できてないんです。
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. …
SvPVMG構造体の予備知識の様な物です。参考URLとリンクします
No.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/perlgut …
Newx(pointer, number, type);
Newxc(pointer, number, type, cast);
Newxz(pointer, number, type); (これだけは獲得した領域を0で埋める)
ケーススタディが多くてXS/Perlgutsの日本語資料はなかなかあたれませんね。
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=c …
http://d.hatena.ne.jp/hiratara/20080625/1214389654
http://www.gadgety.net/shin/tips/unix/perl.html
http://webcache.googleusercontent.com/search?q=c …
動画:
http://www.nicovideo.jp/watch/sm8619094?via=thum …
目を通した所
http://webcache.googleusercontent.com/search?q=c …
http://perldoc.jp/docs/perl/5.14.1/perlcall.pod
http://d.hatena.ne.jp/perlcodesample/20100824/12 …
http://d.hatena.ne.jp/syohex/20110929/1317308531
http://webcache.googleusercontent.com/search?q=c …
http://webcache.googleusercontent.com/search?q=c …
http://webcache.googleusercontent.com/search?q=c …
http://d.hatena.ne.jp/gfx/20090204/1233725975
http://cpansearch.perl.org/src/RURBAN/illguts-0. …
http://webcache.googleusercontent.com/
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- C言語・C++・C# 未解決の外部シンボル _printfが関数_mainで参照されました 1 2022/09/18 15:28
- C言語・C++・C# プログラムが書けません。 4 2023/01/22 22:57
- C言語・C++・C# c言語の問題の説明、各所ごとに 5 2023/07/26 11:03
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- C言語・C++・C# C言語(構造体) 3 2022/07/05 20:08
- CGI perlで書いたcgiでsqliteの使い方を教えてください 2 2023/05/08 21:29
- JavaScript jQueryでのドラッグアンドドロップについて 1 2022/07/07 21:04
- C言語・C++・C# C言語初心者 構造体 課題について 2 2023/03/10 19:48
- C言語・C++・C# プログラミング c言語 4 2023/03/07 01:05
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
pythonでDBのカラム名で取得し...
-
構造体のソートの方法について...
-
POSTで配列のデータを渡す方法は?
-
stable diffusionのエラー
-
C言語 構造体の名前欄?を小文...
-
C言語の構造体にてバブルソート...
-
テキストファイルの結合について
-
関数マクロの書き方
-
printfの%eで指数部分の桁数を...
-
linuxのシェルでファイル名に先...
-
matlabでのRRI検出
-
'dataType' 引数を Null にする...
-
ループ変数の変更
-
c言語での wavファイルの編集(...
-
平滑化フィルタ
-
UTF-8で5~6バイトになる文字コ...
-
10Mバイトて文字数に すると何...
-
COBOLのCOMP形式について
-
Excel VBA メール作成について ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
ポインター引数の関数でコンパ...
-
stable diffusionのエラー
-
printfの%eで指数部分の桁数を...
-
エクセルVBA:日付データの変換...
-
int型(2バイト)データの分割
-
c言語の多次元配列で1から100ま...
-
C#でのswitch文
-
【Excel VBA】10進数を2進数に...
-
途中経過も表示するプログラム
-
CreateProcessでの環境変数の設...
-
pythonでDBのカラム名で取得し...
-
C言語についてです! 同じ年の...
-
linuxのシェルでファイル名に先...
-
c言語 配列から数字だけをint型...
-
c言語での wavファイルの編集(...
-
matlabのソースコードをpython...
-
ビットデータのチェック方法
-
10個の実数に対する降順ソート...
-
python 気象データの取得
-
C言語の構造体にてバブルソート...
おすすめ情報