Pointerをarray of Charに変換するには


  2004-09-25 02:35:41  No: 11094

どうもDelphiのポインタと配列の関係が苦手です。
ストリームに格納されているデータ(Pointer型)を
test(aaa:array of char)
という関数に渡したいのですが、うまいこといきません。
何か良い方法があれば教えていただきたいのですが・・・。
私にはwork:array [0..10000] of Char;
という配列を用意して、一旦ここにコピーしてtestに渡す。
という手段した浮かんできません。ただ、サイズが不定なため、
これはやりたくないんです・・。
わけあってtest関数の引数は変更できない状況なので、
渡す方法をご教授お願いします。


bob  2004-09-25 03:29:27  No: 11095

あんまり深く呼んでないのですが、PCharじゃだめ?

そもそも”ストリームに格納されているデータ(Pointer型)”
ってどんな形なんでしょう?


  2004-09-25 03:35:04  No: 11096

ストリームに格納されているデータはバイナリデータです。
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;


jok  2004-09-25 03:46:42  No: 11097

オープン配列パラメータと動的配列は、見かけ上同じなので、メソッドの引数に
するとわたしなどは混乱します。予め、型宣言をしておくことをすすめます。

type
  TBuffArray = array of Char;

のように。そして SetLength()した後にストリームからコピーし、

procedure TForm1.test(aaa:TBuffArray);

に渡すといいです。Size はいりません。High() が使えます。


  2004-09-25 03:54:32  No: 11098

jok様

その方法も試したんですけど確かできませんでした。
ArrayとTBuffArrayには互換性がないって出ちゃいます。

ちなみにtest関数の引数は訳あって変更できない状況です・・・。
procedure TForm1.test(aaa:array of char; size:integer);


jok  2004-09-25 04:24:45  No: 11099

こんな感じで参考になるかな

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;


  2004-09-28 01:47:23  No: 11100

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の違いがわかっていないんですね、
どうも同じように思えてしまって・・・


bob  2004-09-28 02:10:05  No: 11101

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;


bob  2004-09-28 02:12:05  No: 11102

「test関数の引数は変更できない」のか。
ちょっと調べてみる。


bob  2004-09-28 02:49:28  No: 11103

jokさんのサンプル見てよく考えたら、別にarray of charに
こだわる必要が無いのでは?

    mStream.Read(tmpStr[1], mStream.Size);
    test(tmpStr[1], mStream.Size);

一応出来たっぽいよ。文字化けしたけど--;


bob  2004-09-28 02:50:04  No: 11104

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;


bob  2004-09-28 03:01:11  No: 11105

よく考えたら、文字化けするの当たり前か。。。
別にポインタ渡している訳じゃないんだから...


bob  2004-09-28 03:10:46  No: 11106

http://kakinotane.s7.xrea.com/delphi/faq/f001.html
に書いてある
「Pascal は型に厳しい言語なので、まったく同じ内容であっても、違う場所で宣言された型は互換性がなくなります。」
って事なのかな?


※返信する前に利用規約をご確認ください。

※Google reCAPTCHA認証からCloudflare Turnstile認証へ変更しました。






  このエントリーをはてなブックマークに追加