Recent

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

Thaddy

  • Hero Member
  • *****
  • Posts: 14158
  • Probably until I exterminate Putin.
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #15 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 »
Specialize a type, not a var.

TCH

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

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #17 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 »

SymbolicFrank

  • Hero Member
  • *****
  • Posts: 1313
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #18 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: 3197
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #19 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

PascalDragon

  • Hero Member
  • *****
  • Posts: 5444
  • Compiler Developer
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #20 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: 1313
Re: Pascal const Record array stored identically as a C const struct array?
« Reply #21 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