Avatar billede ruma1974 Nybegynder
12. november 2004 - 08:17 Der er 15 kommentarer og
1 løsning

Returnere en array of integer fra en component?

Hej eksperter,

Jeg har lavt et simpelt eksemple som skal returnere en talrække fra en funktion i en component og det virker ikke for mig.

Component kode:

function TMycomp.transform(tal: array of integer): talrkke;
var
I:integer;
nyetal:talrkke;
begin
setlength(nyetal.tal,length(tal));
for I:=0 to length(tal)-1 do
  begin
  nyetal.tal[I]:=tal[I]+1;
  end;
result:=nyetal;
end;

talrkke har jeg defineret som:

type
    talrkke=record
    tal:array of integer;
    end;

Funktionen som kalder componenten

function TMycomp.transform(tal: array of integer): talrkke;
var
I:integer;
nyetal:talrkke;
begin
setlength(nyetal.tal,length(tal));
for I:=0 to length(tal)-1 do
  begin
  nyetal.tal[I]:=tal[I]+1;
  end;
result:=nyetal;
end;

Programmet kompillere fint men går i stå når jeg definere den nye længde af nyetal.tal i funktionen transform. Hvordan gør man dette korrekt?

De bedste hilsner,

Rune
Avatar billede martinlind Nybegynder
12. november 2004 - 08:24 #1
setlength(nyetal.tal,high(tal));
Avatar billede ruma1974 Nybegynder
12. november 2004 - 08:39 #2
Jeg får stadig access violation

high er så vidt jeg ved = length-1

så med high bliver array'et forkort

Rettelse -> Funktion som kalder er

procedure TForm1.Button1Click(Sender: TObject);
var
I:integer;
tal:talrkke;
tal2:array of integer;
begin
setlength(tal2,10);
for I:=0 to 10 do
  begin
  tal2[I]:=I;
  end;
tal:=Mycomp1.transform(tal2);
for I:=0 to 10 do
    begin
    memo1.lines.add(floattostr(tal.tal[I]));
    end;
end;
Avatar billede martinlind Nybegynder
12. november 2004 - 08:43 #3
hvis du kigger i hjælpen, så bruger de high til open arrays

for I := 0 to high(MyArr)
Avatar billede ruma1974 Nybegynder
12. november 2004 - 09:14 #4
Fint nok - men jeg tror ikke det er der problemet er

Jeg kan skrive

setlength(nyetal.tal,length(tal));

setlength(nyetal.tal,high(tal)+1);

setlength(nyetal.tal,11); //da jeg i dette tilfælde kender længden

Det burde værre ligegyldigt. Problemet er at jeg ikke kan ændre længden på nyetal.tal i min component uden at jeg får access violation.
Avatar billede martinlind Nybegynder
12. november 2004 - 09:41 #5
hvor erkærer du din comp. og creater den ???, det tror jeg du mangler, det giver typisk en access violation hvis du tilgår et object/comp uden den er createt
Avatar billede ruma1974 Nybegynder
12. november 2004 - 10:10 #6
Det er nok mere her at der er et problem. Jeg skal bruge den i form1.

type
  TForm1 = class(TForm)
    Mycomp1: TMycomp;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

Jeg kan godt hente en string og en integer fra componenten når de er defineret i public eller published i componenten. Jeg kan også bruge proceduren execute.

Jeg har dog ikke brugt create. Jeg har prøvet Mycomp1.create men det virker ikke.

Hele source koden for componenten er:

unit Mycomp;

interface

uses
  Windows,SysUtils, Classes,Messages, Variants, Graphics, Controls, Forms,
  Dialogs;

type
    talrkke=record
    tal:array of integer;
    end;

type
  TMycomp = class(TComponent)
  private
    FMyStr: string;
    FMyInt: Integer;
    procedure SetMyStr(const Value: string);
    { Private declarations }
  protected
    { Protected declarations }
  public
  constructor create(AOwner : TComponent); override;
  property MyInt : Integer read FMyInt write FmyInt;
  procedure Execute;
  function transform(tal:array of integer):talrkke;
    { Public declarations }
  published
  property MyStr : string read FMyStr write SetMyStr;
    { Published declarations }
  end;

procedure Register;

implementation

procedure Register;
begin
  RegisterComponents('Samples', [TMycomp]);
end;

{ TMycomp }

constructor TMycomp.create(AOwner: TComponent);
begin
inherited create(Aowner);

  FMyInt := 5;
end;

procedure TMycomp.Execute;
begin
  ShowMessage('This is the execute method');
end;

procedure TMycomp.SetMyStr(const Value: string);
begin
  FMyStr := Value;
end;

function TMycomp.transform(tal: array of integer): talrkke;
var
I:integer;
nyetal:talrkke;
begin
setlength(nyetal.tal,11);
for I:=0 to length(tal)-1 do
  begin
  nyetal.tal[I]:=tal[I]+1;
  end;
result:=nyetal;
end;

end.

Koden for unit som kalder componenten er:

unit CompU;

interface

uses
  Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
  Dialogs, StdCtrls, Mycomp;

type
  TForm1 = class(TForm)
    Mycomp1: TMycomp;
    Button1: TButton;
    Memo1: TMemo;
    procedure Button1Click(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
var
I:integer;
tal:talrkke;
tal2:array of integer;
begin
//mycomp1.create();
setlength(tal2,10);
for I:=0 to 10 do
  begin
  tal2[I]:=I;
  end;
tal:=Mycomp1.transform(tal2);
for I:=0 to 10 do
    begin
    memo1.lines.add(floattostr(tal.tal[I]));
    end;
end;

end.
Avatar billede martinlind Nybegynder
12. november 2004 - 10:18 #7
sider på job, har ikke lige tid nu, men hvis du ikke har fået et svar iaften kigger jeg på det
Avatar billede ruma1974 Nybegynder
12. november 2004 - 10:24 #8
Mange tak
Avatar billede nop Nybegynder
12. november 2004 - 12:28 #9
man kan ikke sætte length på et dynamisk array når det er overført som parameter, jeg har læst det i delphi hjælp mener jeg !
Avatar billede ruma1974 Nybegynder
12. november 2004 - 13:41 #10
Jeg overfør tal som er en array of integer.

nyetal.tal er et nyt array som ikke er blevet overført
Avatar billede doc404 Novice
12. november 2004 - 14:59 #11
Placerer du en TMyComp på Form1?

Den Create() du har udkommenterer er gal. Den skal være

MyComp1 := TMyComp1.Create(Form1);
Avatar billede doc404 Novice
12. november 2004 - 15:00 #12
hov..

Men du skal ikke manuelt Create en component, hvis du trækker den ned fra Samples tabben...
Avatar billede ruma1974 Nybegynder
12. november 2004 - 15:06 #13
Jeg trækker den ned fra tabben så den skal forblive udkommenteret. Componenten virker bortset fra returneringen af nyetal.tal som er et array af integer
Avatar billede doc404 Novice
12. november 2004 - 16:26 #14
Tror du bliver snyt mht. til stedet hvor din AV opstår.

setlength(tal2,10);    <<--- Skal være 11
for I:=0 to 10 do      << -- eller og skal den rettes til 0 to 9
  begin
  tal2[I]:=I;
  end;
tal:=Mycomp1.transform(tal2);
for I:=0 to 10 do      <<------ gal
    begin
    memo1.lines.add(floattostr(tal.tal[I]));
    end;
end;

Du kører en for langt... Brug altid 0 to High(Array) - også selvom du bare tester
Avatar billede ruma1974 Nybegynder
12. november 2004 - 17:29 #15
Hmm du har ret. Jeg blev snydt. Min debuger angav at fjelen opstod i componenten selvom det rent faktisk er hvor du angiver. Pinligt...

Men cool at jeg nu kan lave componenter der returner vilkårlige data typer :-)

doc404 hvis du laver et svar får du point. Måske vi skulle give lidt til Martin Lind også.
Avatar billede doc404 Novice
12. november 2004 - 18:33 #16
;-) del du bare...
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester