どうもDelphiのポインタと配列の関係が苦手です。
ストリームに格納されているデータ(Pointer型)を
test(aaa:array of char)
という関数に渡したいのですが、うまいこといきません。
何か良い方法があれば教えていただきたいのですが・・・。
私にはwork:array [0..10000] of Char;
という配列を用意して、一旦ここにコピーしてtestに渡す。
という手段した浮かんできません。ただ、サイズが不定なため、
これはやりたくないんです・・。
わけあってtest関数の引数は変更できない状況なので、
渡す方法をご教授お願いします。
あんまり深く呼んでないのですが、PCharじゃだめ?
そもそも”ストリームに格納されているデータ(Pointer型)”
ってどんな形なんでしょう?
ストリームに格納されているデータはバイナリデータです。
PChar(mStram.Memory)は、やってみましたがダメでした。
procedure TForm1.func1;
var
mStream:TMemoryStream;
begin
mStream := TMemoryStream.Create;
mStream.LoadFromFile(Edit.Text);
//↓ここにmStram.Memoryを渡したいんですけど・・・
test(???, mStream.Size);
mStream.Free;
end;
procedure TForm1.test(aaa:array of char; size:integer);
begin
:
:
end;
オープン配列パラメータと動的配列は、見かけ上同じなので、メソッドの引数に
するとわたしなどは混乱します。予め、型宣言をしておくことをすすめます。
type
TBuffArray = array of Char;
のように。そして SetLength()した後にストリームからコピーし、
procedure TForm1.test(aaa:TBuffArray);
に渡すといいです。Size はいりません。High() が使えます。
jok様
その方法も試したんですけど確かできませんでした。
ArrayとTBuffArrayには互換性がないって出ちゃいます。
ちなみにtest関数の引数は訳あって変更できない状況です・・・。
procedure TForm1.test(aaa:array of char; size:integer);
こんな感じで参考になるかな
procedure TForm1.func1;
var
mStream:TMemoryStream;
aaa:array[0..1000] of Char;
s:string;
begin
s := 'あいうえお123ABCxyz';
mStream := TMemoryStream.Create;
try
mStream.Write(PChar(s)^,Length(s));
mStream.Position := 0;
mStream.Read(aaa[0],mStream.Size);// ここでコピー
test(aaa, mStream.Size);
finally
mStream.Free;
end;
end;
procedure TForm1.test(aaa: array of char; size: integer);
var
s:string;
begin
SetLength(s,size);
Move(aaa[0],s[1],size);
Memo1.Text := s;
end;
procedure TForm1.Button1Click(Sender: TObject);
begin
func1;
end;
jok様、返事が遅くなって申し訳ありません。
やはり
aaa:array[0..1000] of Char;
というように配列を宣言しないとダメなんですね。
type
TBuffArray = array of Char;
こちらは、渡す方と渡される方、両方の宣言をTBuffArrayにしたらできましたが、
渡される方が都合により修正不可能なので、残念ですが、使えませんでした。
Cだったらこうですよね、
test(aaa: array of char; size: integer);
これは
test(char* p_aaa; size: integer);
こうですよね?
渡す方の型がint* pだとしたら、
test((char*)p, size);
と、キャストすれば違う型でも渡せますよね。
これに似たような事ができればなぁ・・・と。
書いて思ったのですが、
PCharとarray of charの違いがわかっていないんですね、
どうも同じように思えてしまって・・・
type
TBuffArray = array of Char;
TForm1 = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private 宣言 }
procedure test(Buff: TBuffArray);
public
{ Public 宣言 }
end;
var
Form1: TForm1;
implementation
{$R *.dfm}
procedure TForm1.Button1Click(Sender: TObject);
var
mStream:TMemoryStream;
tmpStr: String;
tmpChars: TBuffArray;
begin
tmpStr := 'あいうえお123ABCxyz';
mStream := TMemoryStream.Create;
try
//mStream.LoadFromFile(Edit.Text);
mStream.Write(PChar(tmpStr)^,Length(tmpStr));
mStream.Position := 0;
SetLength(tmpChars, mStream.Size);
mStream.Read(tmpChars[0], mStream.Size);
test(tmpChars);
finally
mStream.Free;
end;
end;
procedure TForm1.test(Buff: TBuffArray);
begin
Form1.Caption := String(Buff);
end;
「test関数の引数は変更できない」のか。
ちょっと調べてみる。
jokさんのサンプル見てよく考えたら、別にarray of charに
こだわる必要が無いのでは?
mStream.Read(tmpStr[1], mStream.Size);
test(tmpStr[1], mStream.Size);
一応出来たっぽいよ。文字化けしたけど--;
procedure TForm1.test(aaa:array of char; size: integer);
var
tmpStr:string;
begin
SetLength(tmpStr, size);
Move(aaa[0], tmpStr[1], size);
form1.Caption := tmpStr;
end;
よく考えたら、文字化けするの当たり前か。。。
別にポインタ渡している訳じゃないんだから...
http://kakinotane.s7.xrea.com/delphi/faq/f001.html
に書いてある
「Pascal は型に厳しい言語なので、まったく同じ内容であっても、違う場所で宣言された型は互換性がなくなります。」
って事なのかな?
ツイート | ![]() |