[fpc-pascal] stuck with untyped pointer

Alberto Narduzzi albertonarduzzi at yahoo.com
Fri May 28 19:51:10 CEST 2010


>    i := self.names.indexOf(name);
>    val := Struct(self.values[i]);
> raises "got untyped expected Struct". Sure, that's why I'm trying to cast... Without casting to Struct, the compiler indeed throws "got pointer expected Struct". I'm very surprised since I already did this.

in first place, you can omit self within the object's methods, as it's 
implicitly there.

second, the property Values[] expects a string inside "[]" and not a 
number, so you may want to use val := Values[name];

third, Values return a string (the rightmost part of the "=" if you read 
the items property (or directly l[n])), so you cannot cast it to "Struct".

I think you intend to do something like:

Var
MyStruct: Struct;
MyList: TStringList;
I: Integer;

(...)

MyList := TStringList.Create();

(...)

For I := 0 To 10 Do
Begin
   MyStruct := Struct.struct(I);
   MyList.AddObject(Format('struct no. %d', [I]), TObject(MyStruct));
End;

{cannot remember whether the casting to TObject is necessary or not, or 
any syntax error I might have done, because I'm typing it out of my 
mind, after a year or so I haven't written any pascal code... anyway, I 
suggest you derive your Struct from TObject. And for a matter of 
readability, I also suggest you name it TStruct instead of plainly 
Struct, but this is a matter of taste}

(...)

you can now retrieve the objects you added with:

For I := 0 To Pred(MyList.ItemsCount) Do
Begin
   MyStruct := Struct(MyList.Objects[I]);
   ...do whatever you like with your struct variable here...
End;

If you need to retrieve your objects using the "names" you need to do 
something like:

I := MyList.IndexOfName("struct no. 6");
If(I >= 0)
   MyStruct := Struct(MyList.Objects[I]);

or more rapidly, if you are sure the "name" exists, with

MyStruct := Struct(MyList.Objects[MyList.IndexOfName("struct no. 6")]);


bear in mind that free-ing MyList does not free the instances of Struct 
you have created and inserted; so you need to do it manually, in another 
for-cycle, for example...

For I := 0 To Pred(MyList.ItemsCount) Do
Begin
   MyStruct := Struct(MyList.Objects[I]);
   MyStruct.Free;
End;

If you intended to retrieve your objects directly with Names[] and 
Values[] then forget it. Unless you descend from TStrings and write the 
property accordingly (and all the other virtual methods, of course)

Or you can descend from TStringList (don't know if this is the best 
thing you could do, but...), and add a property ObjectValues, with a 
proper Getter and Setter expecting a string instead of an integer; like:

property ObjectValues[const AName:String]: TObject Read GetObjectValue 
write SetObjectValue;

Function TMyStringList.GetObjectValue(const AName:String):TObject;
Var I:Integer;
Begin
   Result := Nil;
   I := IndexOfName(AName);
   If (I >= 0) Then
     Result := Objects[I];
End;

Procedure TMyStringList.SetObjectValue(const AName:String; AObject:TObject);
Var I:Integer;
Begin
   I := IndexOfName(AName);
   If (I >= 0) Then
     Objects[I] := AObject;
End;


As I said, take all this with a grain of salt, as I may have written 
mistakes and/or forgot something.

Just my 2c, hope this helps.


Cheers, A.



More information about the fpc-pascal mailing list