Jump to content
Andre1

Access violation with move command

Recommended Posts

Hi, 
this is a simplified example. I need to do generic calling. In procedure Main, while calling the Move command,
an access violation is triggered. Why is the ByteArray not sucessfully filled?

 

program Project1;

{$APPTYPE CONSOLE}

{$R *.res}

uses
  System.SysUtils,
  System.Rtti;

type
  TMidiInputEvent = packed record
    Timestamp: Integer;
    Status: Byte;
    Data1: Byte;
    Data2: Byte;
  end;

  TMyObject = class
  public
    procedure TargetMethod(p: PPointer; len: PInteger);
    procedure CallMethodByName(const AMethodName: string; p: PPointer; len: PInteger);
  end;

procedure TMyObject.TargetMethod(p: PPointer; len: PInteger);
var
  EventCount: Integer;
  Events: TArray<TMidiInputEvent>;
  TotalSize: NativeUInt;
  I: Integer;
begin
  SetLength(Events, 5); // 5 sample events
  for I := 0 to High(Events) do
  begin
    Events[I].Timestamp := 1000 + I * 100;
    Events[I].Status := $90; // Note On
    Events[I].Data1 := 60 + I; // MIDI note number
    Events[I].Data2 := 100; // Velocity
  end;
  EventCount := 5;

  TotalSize := EventCount * SizeOf(TMidiInputEvent);
  GetMem(p^, TotalSize);
  Move(Events[0], p^, TotalSize);
  len^ := TotalSize;
end;

procedure TMyObject.CallMethodByName(const AMethodName: string; p: PPointer; len: PInteger);
var
  RttiContext: TRttiContext;
  RttiType: TRttiType;
  RttiMethod: TRttiMethod;
  Args: TArray<TValue>;
begin
  RttiContext := TRttiContext.Create;
  try
    RttiType := RttiContext.GetType(Self.ClassType);
    RttiMethod := RttiType.GetMethod(AMethodName);

    if Assigned(RttiMethod) then
    begin
      SetLength(Args, 2);
      Args[0] := TValue.From<PPointer>(p);
      Args[1] := TValue.From<PInteger>(len);

      RttiMethod.Invoke(Self, Args);
    end
    else
    begin
      WriteLn(Format('Method ''%s'' not found.', [AMethodName]));
    end;
  finally
    RttiContext.Free;
  end;
end;


procedure Main;
var
  MyObj: TMyObject;
  Data: Pointer;
  DataSize: Integer;
  ByteArray: TBytes;
  TotalBytes: Integer;
begin
  MyObj := TMyObject.Create;
  try
    MyObj.CallMethodByName('TargetMethod', @Data, @DataSize);

 if (Data <> nil) and (DataSize > 0) then
    try
      TotalBytes := DataSize;
      SetLength(ByteArray, TotalBytes);
      // -------> Error occurs here
      Move(Data^, ByteArray[0], TotalBytes);
    finally
      FreeMem(Data);
    end;
  finally
    MyObj.Free;
  end;
end;

begin
  try
    Main;
  except
    on E: Exception do
      Writeln(E.ClassName, ': ', E.Message);
  end;
end.

Kind regards

André

Share this post


Link to post

Hi,

I found the issue, it needs to be:

 

Move(Data, ByteArray[0], TotalBytes);


 

Kind regards
André

 

Share this post


Link to post

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

×