1

void 型パラメーターを使用して 2 つのメソッドを作成しました。

procedure Method1(const MyVar; size: cardinal);
var
  Arr: array of byte;
begin
  SetLength(Arr, size);
  {now copy the data from MyVar to Arr, but how?}  
end;

procedure Method2(var MyVar; size: cardinal);
var
  Arr: array of byte;
begin
  SetLength(Arr, size);
  {return the data from the array, but how?}
end;

最初のものでは、バイトの配列として MyVar にアクセスしたいと思います。2 つ目は、ローカル配列 Arr から MyVar にデータをコピーしたいと考えています。そのため、CopyMemory() 関数を使用しましたが、何か問題があります。

2 番目のメソッドで次を使用する場合、Method2 がパラメーターとして配列を使用して呼び出される限り問題ありません (Method2(Pointer(MyString)^, Length(MyString)) または Method2(Pointer(MyArray), Length(MyArray))。 ))))。

CopyMemory(Pointer(MyVar), Pointer(Arr), size);

たとえば、整数パラメーター (Method2(MyInteger, SizeOf(MyInteger))) を指定して Method2 を呼び出すと、正しく動作しません。この場合、CopyMemory() は次のように呼び出す必要があります。

CopyMemory(@MyVar, Pointer(Arr), size);

単純型 (またはレコード) か配列かがわからない Method2 からデータを正しく返す方法は? Method1 でも状況は似ていますが、ここでは使用する必要があります。

CopyMemory(Pointer(Arr), Pointer(MyVar), size);

配列の場合

CopyMemory(Pointer(Arr), @MyVar, size);

シンプルタイプの場合。

MyVar パラメータがわからない場合はどうすればよいですか?

4

2 に答える 2

4

問題は、データまたはデータへのポインターのいずれかを Method1/2 に渡すことです。常にデータ自体を渡す必要があります。動的配列自体がポインターであることを忘れてしまったのではないでしょうか? メソッドに A または Pointer(A) を渡さないでください (ここでは A は動的配列です)。A[0] または Pointer(A)^ を渡します。

procedure Method1(const MyVar; size: cardinal);
var
  Arr: array of byte;
begin
  SetLength(Arr, size);
  CopyMemory(Pointer(Arr), @MyVar, Size);
end;

procedure Method2(var MyVar; size: cardinal);
var
  Arr: array of byte;
begin
  SetLength(Arr, size);
  Arr[0] := 1;
  Arr[1] := 2;
  Arr[2] := 3;
  Arr[3] := 4;
  CopyMemory(@MyVar, Pointer(Arr), Size);
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  I: Integer;
  A: array of Integer;
begin
  I := $01020304;
  Method1(I, 4); // we pass data itself, not the pointer to it.
  Method2(I, 4);
  SetLength(A, 2);
  A[0] := 0;
  A[1] := $01020304;
  Method1(A[0], Length(A) * SizeOf(A[0])); // note, that we pass data, not pointer
  Method2(A[0], Length(A) * SizeOf(A[0])); // A or Pointer(A) is a pointer to array's data
end;

A が動的配列の場合:

  1. A[0] は Pointer(A)^ と同じで、配列のデータを表します。
  2. @A[0] は Pointer(A) または単に A と同じであり、そのデータへのポインターである配列自体を表します (および負のオフセットに関するいくつかの技術情報)。

A が静的配列の場合:

  1. A[0] は A と同じで、配列のデータである配列自体を表します。
  2. @A[0] は @A と同じで、配列へのポインタを表します。
  3. Pointer(A) または Pointer(A)^ は無意味です。

Method1/2 の Arr も動的配列であることに注意してください。そのため、これをポインターにキャストします (CopyMemory はデータではなくポインターを要求します)。Move ルーチン (データを要求する) を使用する場合は、代わりに Pointer(A)^ を記述する必要があります。

于 2009-07-08T21:26:32.373 に答える