How to Copy a Record data to a buffer?

classic Classic list List threaded Threaded
75 messages Options
1234
Reply | Threaded
Open this post in threaded view
|

How to Copy a Record data to a buffer?

yu ping
TCommsBuffer = packed record
    UnitID: Byte;
    FunctionCode: TModBusFunction;
    MBPData: TModBusDataBuffer;
    Spare: Byte;
  end; { TCommsBuffer }


SendBuffer: TCommsBuffer;

--------------------------
I want to send the data in SendBuffer to serial port
I define a array type:

rcvData:TDataByte;(TDataByte = array of byte)
setlength(rcvData, sizeof(SendBuffer ) );
count := datatosend;
CopyMemory( @rcvData, @ SendBuffer , count);
SeriComm.SendBuffer(@rcvData,count);

when run to "CopyMemory( @rcvData, @ SendBuffer , count);" the program crash,
what's wrong with me? Thanks.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: How to Copy a Record data to a buffer?

Matthias K.-2
Hi,
either use "Move( SendBuffer, rcvData, count )" (recommended since its
from rtl, not windows api) or
"CopyMemory( @rcvData[0], @SendBuffer, count )".
Its a common mistake to use @<dynamic array var> instead of @<dynamic
array var>[ 0 ].

regards

On Sat, Oct 10, 2009 at 11:51 AM, yu ping <[hidden email]> wrote:

> TCommsBuffer = packed record
>    UnitID: Byte;
>    FunctionCode: TModBusFunction;
>    MBPData: TModBusDataBuffer;
>    Spare: Byte;
>  end; { TCommsBuffer }
>
>
> SendBuffer: TCommsBuffer;
>
> --------------------------
> I want to send the data in SendBuffer to serial port
> I define a array type:
>
> rcvData:TDataByte;(TDataByte = array of byte)
> setlength(rcvData, sizeof(SendBuffer ) );
> count := datatosend;
> CopyMemory( @rcvData, @ SendBuffer , count);
> SeriComm.SendBuffer(@rcvData,count);
>
> when run to "CopyMemory( @rcvData, @ SendBuffer , count);" the program crash,
> what's wrong with me? Thanks.
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: How to Copy a Record data to a buffer?

Matthias K.-2
Hi,
For the Move solution, use "Move( SendBuffer, rcvData[0], count )"..
Same common mistake with <dynamic array var>[0].

sry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: How to Copy a Record data to a buffer?

yu ping
Solved,Thanks
there is another mistake:
    FillChar(sendData, high(sendData), 0);
change to
    FillChar(sendData[0], high(sendData), 0);
OK.



2009/10/10 Matthias K. <[hidden email]>:
> Hi,
> For the Move solution, use "Move( SendBuffer, rcvData[0], count )"..
> Same common mistake with <dynamic array var>[0].
>
> sry
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Jürgen Hestermann
In reply to this post by Matthias K.-2
> Its a common mistake to use @<dynamic array var> instead of @<dynamic
> array var>[ 0 ].

IMO this happens because of an illogical design flaw (which seems to be
introduced by Borland). If I have a variable that is a *pointer* to an
array then why is it possible to use the square brackets to use it as if
  it was an array? The derefencing symbol ^ should be needed here (X^[1]
instead of X[1]). It's the same for PCHAR. It is a pointer and there
should not be any automatic derefencing. That obscures the type origin
and is not in the spirit of Pascal. And it leads to the mistakes
mentioned above. It is C-like style ("the compiler will guess what you
meant") which should never have crept into Pascal. If you build a
complex data structure with nested pointers and arrays you get into hell
with this automatic dereferencing.

Well, it is now much too late to change this but it annoys me all the time.

_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Henry Vermaak
2009/10/10 Jürgen Hestermann <[hidden email]>:

>> Its a common mistake to use @<dynamic array var> instead of @<dynamic
>> array var>[ 0 ].
>
> IMO this happens because of an illogical design flaw (which seems to be
> introduced by Borland). If I have a variable that is a *pointer* to an array
> then why is it possible to use the square brackets to use it as if  it was
> an array? The derefencing symbol ^ should be needed here (X^[1] instead of
> X[1]). It's the same for PCHAR. It is a pointer and there should not be any
> automatic derefencing. That obscures the type origin and is not in the
> spirit of Pascal. And it leads to the mistakes mentioned above. It is C-like
> style ("the compiler will guess what you meant") which should never have
> crept into Pascal. If you build a complex data structure with nested
> pointers and arrays you get into hell with this automatic dereferencing.

This behaviour comes from C syntax.  The array is a pointer, which you
dereference by using the square brackets.  This is well defined
syntax, nothing automatic or illogical about it.  The only reason
pascal programmers make mistakes with this is because they are less
accustomed to using pointers.

Henry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Jürgen Hestermann
> This behaviour comes from C syntax.  The array is a pointer, which you
> dereference by using the square brackets.  This is well defined
> syntax, nothing automatic or illogical about it.  The only reason
> pascal programmers make mistakes with this is because they are less
> accustomed to using pointers.

It is illogical that I am able to enumerate a pointer as if it was an
array. So the brackets do the dereferencing automatically. When I write
X[1] it assumes I meant X^[1]. To the user it behaves the same as if X
was an array instead of a pointer to an array. There is no difference in
syntax which is wrong IMO. It's not wonder that many users think it *is*
an array.

That's the same as if I could use square brackets for an integer and the
compiler assumes I meant to pick up one of the bytes. Strict type
checking was a fundamental goal of Pascal but is has now been weakended
by C-style creaping into it. If you are forced to use the first element
of an array in situatons where you wanted to specify the whole array it
is illogical. And it's not that pascal programmers are less accustomed
to pointers, but they are less accustomed to obscure compiler magic. It
has become fashionable to *hide* such things ("you don't need to know
the details") and the syntax doesn't tell the users either which
provokes such mistakes.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Henry Vermaak
2009/10/10 Jürgen Hestermann <[hidden email]>:
>
> It is illogical that I am able to enumerate a pointer as if it was an array.
> So the brackets do the dereferencing automatically. When I write X[1] it
> assumes I meant X^[1]. To the user it behaves the same as if X was an array
> instead of a pointer to an array. There is no difference in syntax which is
> wrong IMO. It's not wonder that many users think it *is* an array.

I can't understand what you are trying to say.  An array is a pointer
to where the elements of the array resides in memory.  How else do you
think it works?  Can you explain what would x[1] mean if it isn't
dereferenced?

>
> That's the same as if I could use square brackets for an integer and the
> compiler assumes I meant to pick up one of the bytes. Strict type checking
> was a fundamental goal of Pascal but is has now been weakended by C-style
> creaping into it. If you are forced to use the first element of an array in
> situatons where you wanted to specify the whole array it is illogical. And
> it's not that pascal programmers are less accustomed to pointers, but they
> are less accustomed to obscure compiler magic. It has become fashionable to
> *hide* such things ("you don't need to know the details") and the syntax
> doesn't tell the users either which provokes such mistakes.

No, it's not weakened by C-style all of a sudden, it's _always_ been
like this.  As I've been trying to explain to you, there's no "obscure
compiler magic", if you put the brackets there, the compiler
dereferences.

Henry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Graeme Geldenhuys-2
In reply to this post by Jürgen Hestermann
2009/10/10 Jürgen Hestermann <[hidden email]>:
>
> It is illogical that I am able to enumerate a pointer as if it was an array.
> So the brackets do the dereferencing automatically. When I write X[1] it
> assumes I meant X^[1]. To the user it behaves the same as if X was an array
> instead of a pointer to an array. There is no difference in syntax which is
> wrong IMO. It's not wonder that many users think it *is* an array.

I have to agree 100%. This is what through me off a few days ago as
well. Plus I haven't used pointers and pointers to array structures in
many years. But yes, the syntax is inconsistent with other syntax
rules.



--
Regards,
  - Graeme -


_______________________________________________
fpGUI - a cross-platform Free Pascal GUI toolkit
http://opensoft.homeip.net/fpgui/
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Henry Vermaak
In reply to this post by Jürgen Hestermann
2009/10/10 Jürgen Hestermann <[hidden email]>:
>
> It is illogical that I am able to enumerate a pointer as if it was an array.
> So the brackets do the dereferencing automatically. When I write X[1] it
> assumes I meant X^[1]. To the user it behaves the same as if X was an array
> instead of a pointer to an array. There is no difference in syntax which is
> wrong IMO. It's not wonder that many users think it *is* an array.

One thing I think you don't understand is that an array _is_ a
pointer.  Look at this table to visualise:

http://en.wikipedia.org/wiki/C_syntax#Accessing_elements

Henry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Marco van de Voort
In our previous episode, Henry Vermaak said:
[ Charset ISO-8859-1 unsupported, converting... ]

> 2009/10/10 J?rgen Hestermann <[hidden email]>:
> >
> > It is illogical that I am able to enumerate a pointer as if it was an array.
> > So the brackets do the dereferencing automatically. When I write X[1] it
> > assumes I meant X^[1]. To the user it behaves the same as if X was an array
> > instead of a pointer to an array. There is no difference in syntax which is
> > wrong IMO. It's not wonder that many users think it *is* an array.
>
> One thing I think you don't understand is that an array _is_ a
> pointer.  Look at this table to visualise:

> http://en.wikipedia.org/wiki/C_syntax#Accessing_elements

That link is talking about interchangability, which is not the same as being
the same.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Henry Vermaak
2009/10/10 Marco van de Voort <[hidden email]>:
>> http://en.wikipedia.org/wiki/C_syntax#Accessing_elements
>
> That link is talking about interchangability, which is not the same as being
> the same.

Yes, I'm just trying to explain that there's no magic to it,
illustrated by some basic pointer arithmetic.

Henry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Marco van de Voort
In our previous episode, Henry Vermaak said:
> >
> > That link is talking about interchangability, which is not the same as being
> > the same.
>
> Yes, I'm just trying to explain that there's no magic to it,
> illustrated by some basic pointer arithmetic.

I think there are several bits that mix in this thread:

1 nearly all types that don't fit in registers are in memory, and you need
   a memory access to reference them. This makes them all
  references/pointers/addresses on assembler level, but not necessary pointers
  on language level.
2 The fact that Delphi mandatory skips a ^ when indexing a pointer + array.
3 The fact that FPC allows both in objfpc mode. (which means)
4 The fact that FPC and Delphi allow pchar to be overindexed.
5 The fact that FPC and Delphi 2009+ with {$pointermath on} also allow it
    for other pointer types.

Note that I write this from memory after porting some FPC bits to Delphi
last week. Most notably the {$pointermath on} (5) and the mandatory aspect
of (2) might be related.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Aleksa Todorovic-2
Also, it is very important to make distinction between static and
dynamic arrays. For static arrays, compiler knows their exact memory
location at compile time (modulo situations where static array is part
of another structure), but for dynamic arrays, compiler only knows
where in memory is reference (akka pointer) to the contents of that
array. So, if we wanted to have that distinction on syntax level, we
would have to use X[1] for static arrays and X^[1] for dynamic arrays.
Doesn't sound nice, does it?


On Sat, Oct 10, 2009 at 15:32, Marco van de Voort <[hidden email]> wrote:

> In our previous episode, Henry Vermaak said:
>> >
>> > That link is talking about interchangability, which is not the same as being
>> > the same.
>>
>> Yes, I'm just trying to explain that there's no magic to it,
>> illustrated by some basic pointer arithmetic.
>
> I think there are several bits that mix in this thread:
>
> 1 nearly all types that don't fit in registers are in memory, and you need
>   a memory access to reference them. This makes them all
>  references/pointers/addresses on assembler level, but not necessary pointers
>  on language level.
> 2 The fact that Delphi mandatory skips a ^ when indexing a pointer + array.
> 3 The fact that FPC allows both in objfpc mode. (which means)
> 4 The fact that FPC and Delphi allow pchar to be overindexed.
> 5 The fact that FPC and Delphi 2009+ with {$pointermath on} also allow it
>    for other pointer types.
>
> Note that I write this from memory after porting some FPC bits to Delphi
> last week. Most notably the {$pointermath on} (5) and the mandatory aspect
> of (2) might be related.
> _______________________________________________
> fpc-pascal maillist  -  [hidden email]
> http://lists.freepascal.org/mailman/listinfo/fpc-pascal
>



--
Aleksa Todorovic - Lead Programmer
Eipix Entertainment
http://www.eipix.com/
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Micha Nelissen
In reply to this post by Henry Vermaak
Henry Vermaak wrote:
> One thing I think you don't understand is that an array _is_ a
> pointer.  Look at this table to visualise:

In Pascal, an array is not a pointer; at least not at the language
level. For a static array X (array[1..n] of T), you *can* write:

Move(Ptr^, X, sizeof(X));

because X *is* the array, representing the memory of the array.

Micha
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Jürgen Hestermann
In reply to this post by Henry Vermaak
> I can't understand what you are trying to say.  An array is a pointer
> to where the elements of the array resides in memory.  How else do you
> think it works?  

just look at:

type ArrayType = array[1..10] of char;
var  X  : ArrayType;
      PX : ^ArrayType

What is the difference between X and PX?

X is an array of char which can be accessed directly. The identifier X
means the address in memory where the array elements 1..10 are stored.
The address of X (@X) is the address of the array (first element).

XP is just a pointer to such a structure. It's not the array itself. The
address of XP (@XP) is the address of the pointer, not the array.

Sizeof(X) is 10 bytes.
Sizeof(PX) is 4 bytes.

Still you can use X[1] and PX[1]. That's illogical.

> No, it's not weakened by C-style all of a sudden, it's _always_ been
> like this.  

It has never been like this (in Pascal). That's C-style.


_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Jürgen Hestermann
In reply to this post by Aleksa Todorovic-2
> Also, it is very important to make distinction between static and
> dynamic arrays. For static arrays, compiler knows their exact memory
> location at compile time (modulo situations where static array is part
> of another structure), but for dynamic arrays, compiler only knows
> where in memory is reference (akka pointer) to the contents of that
> array. So, if we wanted to have that distinction on syntax level, we
> would have to use X[1] for static arrays and X^[1] for dynamic arrays.

Exactly!

> Doesn't sound nice, does it?

To me it does, much more as it's now. It would make it clear what kind
of data structure I am working with. What is not nice with it? Now all
these facts are obscured by some background compiler magic and
misinterpretations are generated.

Imagine a highly nested structure of pointers to arrays of pointers to
arrays of pointers..... If you try to write code to access the data you
will soon get lost what to write if you mean some of the arrays or mean
the pointers.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Henry Vermaak
In reply to this post by Jürgen Hestermann
2009/10/10 Jürgen Hestermann <[hidden email]>:

>> I can't understand what you are trying to say.  An array is a pointer
>> to where the elements of the array resides in memory.  How else do you
>> think it works?
>
> just look at:
>
> type ArrayType = array[1..10] of char;
> var  X  : ArrayType;
>     PX : ^ArrayType
>
> What is the difference between X and PX?
>
> X is an array of char which can be accessed directly. The identifier X means
> the address in memory where the array elements 1..10 are stored. The address
> of X (@X) is the address of the array (first element).
>
> XP is just a pointer to such a structure. It's not the array itself. The
> address of XP (@XP) is the address of the pointer, not the array.
>
> Sizeof(X) is 10 bytes.
> Sizeof(PX) is 4 bytes.
>
> Still you can use X[1] and PX[1]. That's illogical.

Right, I see what you mean, now.  Contrary to what I thought arrays
are not pointers (in syntax, at least), this is indeed confusing.  I
hardly ever use pointer arithmetic in pascal, though, so it doesn't
really bother me.

Henry
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Vinzent Höfler
In reply to this post by Henry Vermaak
Henry Vermaak <[hidden email]>

> I can't understand what you are trying to say.  An array is a pointer
> to where the elements of the array resides in memory.

No, not in Pascal. In Pascal an array is a variable just like any other: A name for some memory area where values can be stored.

> How else do you think it works?

Just like "a : integer" -> reserve the needed number of bytes and let the programmer access the associated memory via the identifier "a".

> Can you explain what would x[1] mean if it isn't dereferenced?

Access the memory at address of "x + 1 * (size of element)".

Just like you do

array4 : record a1, a2, a3, a4 end;

and access the record members respectively. It's a static address, known at compile time. No dereferencing.

> No, it's not weakened by C-style all of a sudden, it's _always_ been
> like this.

No. Your confusing arrays and pointers. Or maybe, you're confusing Pascal and C.

>  As I've been trying to explain to you, there's no "obscure
> compiler magic", if you put the brackets there, the compiler
> dereferences.

The dereferencing operator in Pascal is "^".


Vinzent.

--
GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Illogical automatic dereferencing

Vinzent Höfler
In reply to this post by Henry Vermaak
Henry Vermaak <[hidden email]>:

> One thing I think you don't understand is that an array _is_ a
> pointer.  Look at this table to visualise:
>
> http://en.wikipedia.org/wiki/C_syntax#Accessing_elements

One thing I think you don't understand is that arrays and pointers are orthogonal concepts in almost every other programming language than C.

So technically, C is the one who got it wrong.

Same for "Array subscript numbering begins at 0." - which simply isn't true for Pascal.


Vinzent.
--
GRATIS für alle GMX-Mitglieder: Die maxdome Movie-FLAT!
Jetzt freischalten unter http://portal.gmx.net/de/go/maxdome01
_______________________________________________
fpc-pascal maillist  -  [hidden email]
http://lists.freepascal.org/mailman/listinfo/fpc-pascal
1234