Memory layout of array of variable size.

View: New views
10 Messages — Rating Filter:   Alert me  

Memory layout of array of variable size.

by Bastiaan Veelo :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

In an attempt to hook up to GTK+, I am trying to pass a Pascal array of
varible size to C. Static arrays are fine, but these arrays carry some
additional information like capacity and size, and I gues they could be
received as a struct on the C-side. However, I cannot figure out the
structure that the struc should have.

I do like this in Pascal:

procedure YGTK_init(var argc : CInteger;
                        argv : array of CString); external name 'YGTK_init';
procedure Y_init;
var
   argc    : CInteger;
   argv    : array[0..ParamCount] of CString;
   Counter : integer;
begin
   argc := ParamCount+1;
   for Counter := 0 to ParamCount do
   begin
      argv[Counter] := NewCString(ParamStr(Counter));
   end;
   YGTK_init(argc, argv);
end;

And like this in C:

struct t_argv {
  int end;
  void *argv;
};

void YGTK_init( int *argc, struct t_argv argv )
{
  printf("In ygtk.c:YGTK_init.\n");
  printf("argv.end: %d\n", argv2.argc);
  printf("argv.argv address: %p\n", argv2.argv);
  printf("argv.argv int: %d\n", argv2.argv);
  printf("argv.argv string: %s\n", argv2.argv);
  printf("number of arguments: %d\n", *argc);
}

So I figured out that the first element in the struct is an integer
containing the length-1 of the array, but what it should look like for
the rest I do not know yet. Do you have an idea?

Thanks,
Bastiaan.


Re: Memory layout of array of variable size.

by Bastiaan Veelo :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Markus Gerwinski wrote:

> Your approach relies on compiler-internal specifica that might change with
>
>future implementations of GPC. In C, I'd rather treat the GPC array as a
>pointer and access its contents and schema information with functions.
>
Good thought. Thanks.

Bastiaan.


Re: Memory layout of array of variable size.

by Markus Gerwinski :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Bastiaan Veelo wrote:
> So I figured out that the first element in the struct is an integer
> containing the length-1 of the array, but what it should look like for
> the rest I do not know yet. Do you have an idea?

Your approach relies on compiler-internal specifica that might change with
future implementations of GPC. In C, I'd rather treat the GPC array as a
pointer and access its contents and schema information with functions. Like
this (untested):

Pascal unit:

  type
    CStringArray = array of CString;

  Function CStringArrayAt ( aArray: CStringArray; i: CInteger ): CString; attribute ( name = 'C_string_array_at' );

  [...]

  Function CStringArrayAt ( aArray: CStringArray; i: CInteger ): CString;

  begin (* CStringArrayAt *)
    CStringArrayAt:= aArray [ i ];
  end (* CStringArrayAt *);

C header:

  char* C_string_array_at ( void* a_array, int i );

By this, you don't need to define a struct where you'd have to guess the
correct position of the fields.

Regards,

  Markus


Re: Memory layout of array of variable size.

by Emil Jerabek :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Jul 30, 2006 at 05:44:51PM +0200, Bastiaan Veelo wrote:

> Hi,
>
> In an attempt to hook up to GTK+, I am trying to pass a Pascal array of
> varible size to C. Static arrays are fine, but these arrays carry some
> additional information like capacity and size, and I gues they could be
> received as a struct on the C-side. However, I cannot figure out the
> structure that the struc should have.
>
> I do like this in Pascal:
>
> procedure YGTK_init(var argc : CInteger;
>                        argv : array of CString); external name 'YGTK_init';

If all you need is to pass argc and argv to the library, there are
predefined variables CParamCount and CParameters (of type integer
and PCString, respectively, which matches C int and **char).

Emil Jerabek


CParamCount and CParameters (was: Memory layout of array of variable size.)

by Bastiaan Veelo :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Emil Jerabek wrote:

> If all you need is to pass argc and argv to the library, there are
>
>predefined variables CParamCount and CParameters (of type integer
>and PCString, respectively, which matches C int and **char).
>
>Emil Jerabek
>
>  
>
Yes it is! But I get undeclared identifier errors when using these. Do I
need to pull some switches for it to work?

Thanks,
Bastiaan.


Re: CParamCount and CParameters (was: Memory

by Frank Heckenbach :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Bastiaan Veelo wrote:

> Emil Jerabek wrote:
>
> > If all you need is to pass argc and argv to the library, there are
> >
> >predefined variables CParamCount and CParameters (of type integer
> >and PCString, respectively, which matches C int and **char).
> >
> Yes it is! But I get undeclared identifier errors when using these. Do I
> need to pull some switches for it to work?

In C you have to use the linker name, as revealed in gpc.pas:

  CParamCount: Integer; attribute (name = '_p_CParamCount'); external;
  CParameters: PCStrings; attribute (name = '_p_CParameters'); external;

i.e.:

int _p_CParamCount;
const char **_p_CParameters;

Frank

--
Frank Heckenbach, f.heckenbach@..., http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE  D101 CD02 4C9D 0FE0 E5E8


Re: CParamCount and CParameters (was: Memory layout of array of variable size.)

by Emil Jerabek :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

On Sun, Jul 30, 2006 at 07:55:33PM +0200, Bastiaan Veelo wrote:

> Emil Jerabek wrote:
>
> >If all you need is to pass argc and argv to the library, there are
> >
> >predefined variables CParamCount and CParameters (of type integer
> >and PCString, respectively, which matches C int and **char).
> >
> >Emil Jerabek
> >
> >
> >
> Yes it is! But I get undeclared identifier errors when using these. Do I
> need to pull some switches for it to work?
>

Ah, sorry. I shouldn't have said it is predefined, it is in the gpc unit. So
"import gpc;" will do the trick.

Emil


Re: CParamCount and CParameters (was: Memory

by Frank Heckenbach :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Emil Jerabek wrote:

> Ah, sorry. I shouldn't have said it is predefined, it is in the gpc unit. So
> "import gpc;" will do the trick.

I wrote:

> In C you have to use the linker name, as revealed in gpc.pas:
>
>   CParamCount: Integer; attribute (name = '_p_CParamCount'); external;
>   CParameters: PCStrings; attribute (name = '_p_CParameters'); external;
>
> i.e.:
>
> int _p_CParamCount;
> const char **_p_CParameters;

To avoid confusion, my suggestion was when you want to access the
variables directly from C, Emil's when you want to pass them from
Pascal. In fact, the latter is probably better, as it avoids relying
on the linker name.

Frank

--
Frank Heckenbach, f.heckenbach@..., http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE  D101 CD02 4C9D 0FE0 E5E8


Re: Memory layout of array of variable

by Frank Heckenbach :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Bastiaan Veelo wrote:

> So I figured out that the first element in the struct is an integer
> containing the length-1 of the array, but what it should look like for
> the rest I do not know yet. Do you have an idea?

Just to explain this mystery, for (BP style) open array parameters,
GPC internally passes a hidden parameter containing the high limit
of the array. (BTW, BP open arrays are always shifted to a low limit
of zero, but this array is 0-based anyway already.) So this value
contains the number of parameters (whereas argc in C contains the
number including the 0th parameter, so is one higher). That your
struct works is conincidence. It probably doesn't work on all
platforms and may break with other GPC versions. So if anything, use
a separate parameter in C. However, the type would have to be a
Pascal Integer (not a CInteger) which isn't readily available in C.

However, I'd second what Markus wrote, to avoid relying on this
passing mechanism at all, and pass only things to C that have a
direct counter-part in C. Unfortunately, all higher-level dynamic
array mechanisms (open array, conformant arrays, schemata) don't, so
this often means a formally-unbounded plain array ...

Frank

--
Frank Heckenbach, f.heckenbach@..., http://fjf.gnu.de/, 7977168E
GPC To-Do list, latest features, fixed bugs:
http://www.gnu-pascal.de/todo.html
GPC download signing key: ACB3 79B2 7EB2 B7A7 EFDE  D101 CD02 4C9D 0FE0 E5E8


Re: Memory layout of array of variable size.

by Harmonious Botch :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Bastiaan Veelo wrote:
Hi,

In an attempt to hook up to GTK+, I am trying to pass a Pascal array of
varible size to C...
You don't have to deal with C at all to use GTK.  It has been ported to GPC.  Check out: http://www.mirrorservice.org/sites/www.gnu-pascal.de/contrib/nicola/

If you decide to use it, let me know.  I've already cleaned up one minor bug in it.

LightInTheBox - Buy quality products at wholesale price!