MemoryStreamに割り当てられたデータを
ポインタを使ってアクセスしたいのですが、
どのようにすればよいのでしょう?
割り当てられたデータはMemoryプロパティにあるので、
その先頭を参照したい場合は
p1 := stream.Memory; // p1はポインタ変数
これで問題ないのですが、
このstream.Memoryの先頭から50バイト目を
p2(これもポインタ変数)に割り当てる場合、
どのようにすればよいのでしょう?
p2 := stream.Memory + 50;
はダメでした。いろいろとキャストしてみましたけど
無理だとDelphiに怒られました・・・。
C言語だと
ポインタ変数の内容+整数でいけたと思うんですけど・・・
TStream系ですので、Seekすればよろしいかと思います。
ポインタでの話ですね。
それならば、
p1 := Stream.Memory;
p2 := Stream.Memory;
Inc(p2, 50);
としてやればよろしいかと思います。
げげっ・・
単にポインタ変数のインクリメントでつか・・・。
とほほ・・・
そんなことに2日も悩んでいたとは・・・(呆
どうもありがとうございました。
やってみます。。
・・・と、やってみました。
Inc(p2, 50);
これだと、p2の型サイズぶんインクリメントされてしまいます。
結果、
p1からプラス 50バイト 目を指すのがp2ではなくて、
p1からプラス 50*p2の型バイト数 ぶん先を指してしまいます。
気のせいでしょうか・・。
にしの様、解決しました!
型のサイズ(ポインタ変数)*指定したサイズ(50)
だけ増えてしまうので
Inc(p2, 50);
を
Inc(PChar(p2), 50);
にしてみたらできました。。
どうもありがとうございました。
(まさかIncを使うとは思ってもみませんでした・・)
そうですね。
たとえば、
Memoryの内容が 'abcdefghij' (Memory[0]が'a')のとき、
var
pc: PChar;
pdw: PDWORD;
begin
...
pc := Stream.Memory;
pw := Stream.Memory;
for i := 0 to 4 do
begin
Memo2.Lines.Add(Format('[%d]:%x', [i, Integer(pc^)]));
Memo3.Lines.Add(Format('[%d]:%x', [i, Integer(pw^)]));
Inc(pc, 1);
Inc(pw, 1);
end;
...
end;
としてやると、Memo2, Memo3にはそれぞれ
Memo2
[0]:61
[1]:62
[2]:63
[3]:64
[4]:65
Memo3
[0]:6261
[1]:6463
[2]:6665
[3]:6867
[4]:6A69
と出ます。
つまり、WORDは2バイトの変数なので、1つインクリメントすれば、バイト数としては2バイト分先に進みます。
これは、C/C++でも同じだったと思います。
気になるのであれば、PCharとして先に進ませ、使用するときに必要な型に変換し直せば良いと思います。
はい、C/C++と同じです。
はじめはインクリメントするサイズを50としてして、
(このときは単に50バイトぶんプラスされると思っていた)
私がポインタ変数と言っていたのは構造体のポインタだったので、
インクリメント後のアドレスがとんでもないくらい増えていて
びっくりしました。
「どっからこんな値出てくんだ??」
などと思って、50としていたところを1にしてみたところ、
丁度構造体のサイズと一致したので、
「なるほどねぇ、Cと一緒かぁ・・」
と思いつつ、
(1バイト増やすぅぅ〜・・・)
と考えながらInc関数のヘルプを見てみたら
「X がポインタ型の場合,X は(そのポインタが指す型のサイズ)× N だけインクリメントされます」
となっていたので
「あ、そか。PCharがあったか・・・」
と、解決に至った次第です。。
いつもいつも勉強になります。
いずれ、質問する側ではなく、回答する側になってみたいものです。。
ツイート | ![]() |