Is there a way to do...

General discussion on mikroPascal PRO for PIC.
Post Reply
Author
Message
salex319
Posts: 72
Joined: 28 Nov 2013 01:17

Is there a way to do...

#1 Post by salex319 » 05 Feb 2015 00:04

When I do the following I get the error:

Syntax error: Expected "pointer to data (caption)" but "pointer to cdata (?T0)" found SsProV7_Glcd_SsTP.mpas

Code: Select all

type
  TDisplayElement=record
     top : byte;
     left : byte;
     caption : ^string[1];
     end;

CONST  
  B1Caption = 'Test';

  DisplayElement : array[0..2] of TDisplayElement =
  ((1,1,@B1Caption),(1,1,@B1Caption),(1,1,@B1Caption));


Is there some way to do this.

hadv
Posts: 116
Joined: 29 Mar 2013 12:55

Re: Is there a way to do...

#2 Post by hadv » 05 Feb 2015 00:22

Read the help, search for the @ operator.
Then read the part on pointers, section Pointers and memory space.
It is all explained there.

salex319
Posts: 72
Joined: 28 Nov 2013 01:17

Re: Is there a way to do...

#3 Post by salex319 » 05 Feb 2015 00:46

I've read the MikroPascal Pro for PIC manual extensively and it doesn't help me understand how to accomplish what I'm trying to do without getting an error. I'm pretty sure the problem has to do with the B1Caption constant being in program memory not RAM but I still don't know how to fix that. Are you referring to some other source of help? I don't see anything in the manual on "section pointers." Could you suggest a page number?

hadv
Posts: 116
Joined: 29 Mar 2013 12:55

Re: Is there a way to do...

#4 Post by hadv » 05 Feb 2015 00:59

Open the help.
Select the tab 'Index'.
Type in 'Pointers'.
Click the entry 'pointers'
There is a section (i.e. chapter or whatever you want to call it) 'Pointers and memory spaces'.
The first line addresses your question:
var ptr1: ^const byte; // ptr1 pointer in data space pointing to a byte in code space
Since Pascal is very strict on the correct use of datatypes (lucky us) you probably (not sure if it will work) will have to do the followinging:
change the line
caption : ^string[1];
to
caption : ^const byte;

But I am not sure if this will do what you need.

salex319
Posts: 72
Joined: 28 Nov 2013 01:17

Re: Is there a way to do...

#5 Post by salex319 » 05 Feb 2015 01:41

OK. Good info. Doesn't look good for what I want to do but gives me some new stuff to try. Thanks.

Dany
Posts: 3854
Joined: 18 Jun 2008 11:43
Location: Nieuwpoort, Belgium
Contact:

Re: Is there a way to do...

#6 Post by Dany » 05 Feb 2015 13:04

salex319 wrote:When I do the following I get the error:

Syntax error: Expected "pointer to data (caption)" but "pointer to cdata (?T0)" found SsProV7_Glcd_SsTP.mpas

Code: Select all

type
  TDisplayElement=record
     top : byte;
     left : byte;
     caption : ^string[1];
  end;

CONST  
  B1Caption = 'Test';

  DisplayElement : array[0..2] of TDisplayElement =
  ((1,1,@B1Caption),(1,1,@B1Caption),(1,1,@B1Caption));


Is there some way to do this.
Yes, there is some way: typecast the addresses of the const strings ro the correct type:

Code: Select all

program Const_pointers_test;

{ Declarations section }

type
  TDisplayElement=record
     top : byte;
     left : byte;
     caption : ^ string[1];
     end;

CONST
  B1Caption = 'Test';

  DisplayElement : array[0..2] of TDisplayElement =
  ((1,1,^string[1](@B1Caption)),  // <--
  (1,1,^string[1](@B1Caption)),  // <--
  (1,1,^string[1](@B1Caption))); // <--

var xxx: TDisplayElement;

begin
  { Main program }
  xxx := DisplayElement[0];
  xxx := DisplayElement[1];
  xxx := DisplayElement[2];
  
end.
But why not do it the "Pascal"way?:

Code: Select all

program Const_pointers_test_2;

{ Declarations section }

type
  TDisplayElement=record
     top : byte;
     left : byte;
     caption : string[10]; // <-- define max string length
  end;

CONST

  DisplayElement : array[0..2] of TDisplayElement =
  ((1,1,'Test'),
  (1,1,'Test1'),
  (1,1,'Test2'));

var xxx: TDisplayElement;

begin
  { Main program }
  xxx := DisplayElement[0];
  xxx := DisplayElement[1];
  xxx := DisplayElement[2];

end.
The above code is much more understandable and easy to use... Of course here all the string in the type definition has to have max length...
Kind regards, Dany.
Forget your perfect offering. There is a crack in everything, that's how the light gets in... (L. Cohen)
Remember when we were young? We shone like the sun. (David Gilmour)

salex319
Posts: 72
Joined: 28 Nov 2013 01:17

Re: Is there a way to do...

#7 Post by salex319 » 05 Feb 2015 20:28

Dany

Excellent! I thought there should be a more elegant way to do this. Thanks for your reply. If you see a way to do the following:

I would like to create the DisplayElement data structure in the main program as before but then pass it to a unit that would process it but I can't figure out how to pass the entire structure. Do you know of an elegant way to do that.

Code: Select all

program Const_pointers_test_2;
uses DisplayMgrUnit;

{ Declarations section }

CONST

  DisplayElement : array[0..2] of TDisplayElement =
  ((1,1,'Test'),
  (1,1,'Test1'),
  (1,1,'Test2'));

begin
  { Main program }
  ...
  DisplayMgr(???);  // somehow pass entire data structure
  ...
 
end.

//*************************************************************************************

unit DisplayMgrUnit;

type
  TDisplayElement=record
     top : byte;
     left : byte;
     caption : string[10]; // <-- define max string length
  end;

procedure DisplayMgr(???);

implementation
procedure DisplayMgr(???);
var 
  xxx: TDisplayElement;
  I : byte;

begin
 for i:=0 to 2 do
   begin
       xxx := ???[i];                             // then process the elements here
      // then do something with xxx
   end;

end;

salex319
Posts: 72
Joined: 28 Nov 2013 01:17

Re: Is there a way to do...

#8 Post by salex319 » 05 Feb 2015 22:18

In the absence of a more elegant approach I've been trying stuff and am currently working with the following approach. I pass a pointer to the constant data structure discussed above. This code works fine on the first pass through accessing everything just fine. The line "pdrl:=pdrl+sizeof(TDisplayRec);" where I attempt to adjust the pointer to point to the next element doesn't work. For some reason the pointer is advanced by some much larger amount than 24 which is what sizeof(TDisplayRec) is. I even replaced the sizeof with a constant 24 (see assembly below) and for some reason that results in 64 being added - not any kind of multiple of 24. Can anybody explain this?

Code: Select all

procedure DisplayMgr(pdr : PDisplayRec);
var
    i,j : byte;
    xx  : TDisplayRec;
    pdrl : PDisplayRec;
    ostr : string[12];

begin
 
 pdrl:=pdr;
  xx:=pdrl^;

  while xx.page<20 do

  begin
  j:=length(xx.caption)*6+4;
  Glcd_Rectangle_Round_Edges_Fill(xx.Left,xx.Top,xx.Left+j,xx.Top+12,4,1);
  Glcd_write_Text_Adv(xx.caption,xx.Left+4,xx.Top+3);

  pdrl:=pdrl+sizeof(TDisplayRec);
  xx:=pdrl^;
  end;

end;

Code: Select all

;SsTouchPanelUnit.mpas,66 ::                 pdrl:=pdrl+24;
0x1A54        0x0E40              MOVLW       64
0x1A56        0x2576              ADDWF       DisplayMgr_pdrl, 0, 1
0x1A58        0x6E00              MOVWF       R0 
0x1A5A        0x0E02              MOVLW       2
0x1A5C        0x2177              ADDWFC      DisplayMgr_pdrl+1, 0, 1

janni
Posts: 5373
Joined: 18 Feb 2006 13:17
Contact:

Re: Is there a way to do...

#9 Post by janni » 05 Feb 2015 23:57

salex319 wrote: I even replaced the sizeof with a constant 24 (see assembly below) and for some reason that results in 64 being added - not any kind of multiple of 24. Can anybody explain this?
It's not 64 that's added - it's 576, which is 24*24 :wink: . If you check Help on pointers, you'll notice that adding 1 to a pointer is equivalent to adding length of one object the pointer points to. In other words, what you need is simply to increment the pointer - not add a certain number of bytes to it.

salex319
Posts: 72
Joined: 28 Nov 2013 01:17

Re: Is there a way to do...

#10 Post by salex319 » 06 Feb 2015 00:21

Yes, I see. Thank you. That was driving me nuts!

Post Reply

Return to “mikroPascal PRO for PIC General”