Recent

Author Topic: Pascal const Record array stored identically as a C const struct array?  (Read 7383 times)

Zvoni

  • Hero Member
  • *****
  • Posts: 803
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #15 on: October 17, 2021, 03:10:34 pm »
Thaddy, are you sure?
OP stated in his first post, that he wants to pass those records to a c-lib
One System to rule them all, One IDE to find them,
One Code to bring them all, and to the Framework bind them,
in the Land of Redmond, where the Windows lie
---------------------------------------------------------------------
People call me crazy, because i'm jumping out of perfectly fine aircraft

Thaddy

  • Hero Member
  • *****
  • Posts: 10991
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #16 on: October 17, 2021, 04:38:29 pm »
Thaddy, are you sure?
OP stated in his first post, that he wants to pass those records to a c-lib
Yes, of course. You can simply match the memory layout both ways. On the C side, pointers are required, on the Pascal side not. That is the point.
« Last Edit: October 17, 2021, 04:40:00 pm by Thaddy »
The average programmer productivity is 4-5 hours per day. Peak performance 72 hours for short bursts. MTBF is 1 second or less.

TCH

  • Full Member
  • ***
  • Posts: 148
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #17 on: October 30, 2021, 10:50:22 pm »
Whoops, did not see, that you've replied. Thanks for the insight.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 726
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #18 on: October 31, 2021, 03:56:30 pm »
Isn't it the case that PChar and AnsiString are basically the same, with their length just before it (MyString[-4]), but with a ref count and some more stuff before that? And that the length of a dynamic array is also stored in the 4 bytes just before where the pointer points?

So, shouldn't it work to just declare that dynamic array on the right location and be done with it?

This:

Code: Pascal  [Select][+][-]
  1. table: array of entries;

should be exactly the same as:

Code: C  [Select][+][-]
  1. typedef struct
  2. {
  3.         int size;
  4.         entry *entries;
  5. } table;


On second thought: it isn't. "entry" is a pointer.

Is there a BufferLength before the Length as well?
« Last Edit: October 31, 2021, 04:00:45 pm by SymbolicFrank »

jamie

  • Hero Member
  • *****
  • Posts: 5011
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #19 on: October 31, 2021, 07:09:51 pm »
a PChar has not data for length other than a NULL character in the string at some point.

Ansistring is a managed string which means all data before the actual start of the first character is for use of that string.

 A Pchar can wrap around a manage string because even managed strings insert a #0 at the end just to make sure but is not counted as part of the string. So casting around the managed string will behave like a Pchar with no regard of what info is before it.

 At least that is my take on it.. been that way since I can remember with Delphi.

The only true wisdom is knowing you know nothing

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 726
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #20 on: October 31, 2021, 07:32:27 pm »
a PChar has not data for length other than a NULL character in the string at some point.

In C(++) it doesn't, that is true.

Quote
Ansistring is a managed string which means all data before the actual start of the first character is for use of that string.

 A Pchar can wrap around a manage string because even managed strings insert a #0 at the end just to make sure but is not counted as part of the string. So casting around the managed string will behave like a Pchar with no regard of what info is before it.

 At least that is my take on it.. been that way since I can remember with Delphi.

So, the only difference is that a PChar string has no length? I'm pretty sure it does have that as well. They're exactly the same in FPC and Delphi, as far as I know.


winni

  • Hero Member
  • *****
  • Posts: 2792
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #21 on: October 31, 2021, 08:05:26 pm »
Hi!

Take care if you cast an AnsiString to a Pchar:

Ansistrings can contain any char including #0
If you cast it without checking on #0 the Pchar wil stop at the first position of #0

Winni

jamie

  • Hero Member
  • *****
  • Posts: 5011
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #22 on: November 01, 2021, 01:23:13 am »
a PChar has not data for length other than a NULL character in the string at some point.

In C(++) it doesn't, that is true.

Quote
Ansistring is a managed string which means all data before the actual start of the first character is for use of that string.

 A Pchar can wrap around a manage string because even managed strings insert a #0 at the end just to make sure but is not counted as part of the string. So casting around the managed string will behave like a Pchar with no regard of what info is before it.

 At least that is my take on it.. been that way since I can remember with Delphi.

So, the only difference is that a PChar string has no length? I'm pretty sure it does have that as well. They're exactly the same in FPC and Delphi, as far as I know.

Length checks on Pchars are done by iterating the string until it encounters the first #0. And its slower than using managed strings for that of course.

And as spoken before by i think Winni managed strings can contain a #0 character as a valid character but it only taken into account when using the managed system which references the length of the string via the header just prior to the start of the string. So using a PChar around it will cause a stoppage before getting to the real EOS.

 I don't find a lot of usages having #0 in managed strings however, I guess if all you had was managed strings then I guess you could move any data within them, just have to remember to use RawByteStrings so not to encounter problems with UTF8 encoding on the fly.

 I must confess that I did do something like that with with MODBUS data packets in a project where some data was ASCII and others was length markers CRC's etc. It was att the most convenient step to moving managed memory around.

The only true wisdom is knowing you know nothing

PascalDragon

  • Hero Member
  • *****
  • Posts: 3492
  • Compiler Developer
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #23 on: November 02, 2021, 01:57:10 pm »
Isn't it the case that PChar and AnsiString are basically the same, with their length just before it (MyString[-4]), but with a ref count and some more stuff before that? And that the length of a dynamic array is also stored in the 4 bytes just before where the pointer points?

You can relatively cheaply cast a AnsiString to a PChar, because an AnsiString has the string data followed by a NUL and the pointer points to the first character (just like a PChar). There is special handling however for an empty string as that is Nil for an AnsiString, but a pointer to a NUL character for a PChar.

So, shouldn't it work to just declare that dynamic array on the right location and be done with it?

This:

Code: Pascal  [Select][+][-]
  1. table: array of entries;

should be exactly the same as:

Code: C  [Select][+][-]
  1. typedef struct
  2. {
  3.         int size;
  4.         entry *entries;
  5. } table;


On second thought: it isn't. "entry" is a pointer.

Is there a BufferLength before the Length as well?

The header record of a dynamic array contains the highest element as well as the reference count.

But if you have a C-struct like this:

Code: C  [Select][+][-]
  1. typedef struct {
  2.   // whatever
  3. } Element;
  4.  
  5. typedef struct {
  6.   Element* entries;
  7. } Table;

You can abuse the fact that a dynamic array points to the first element as long as the C code does not modify the data (the header record won't be accessed by C code):

Code: Pascal  [Select][+][-]
  1. type
  2.   TElement = record
  3.     // whatever
  4.   end;
  5.  
  6.   TTable = record
  7.     entries: array of TElement;
  8.   end;

That is probably what Thaddy had meant with matching the memory layout.

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 726
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #24 on: November 03, 2021, 11:48:49 am »
Yes, I expect the memory management is the real problem.You might be able to make the array smaller (when RefCount = 1), but expanding requires copying it to a new location. And C++ doesn't know the size of the buffer.

So, calling functions is probably the best way to make it multi-language.

 

TinyPortal © 2005-2018