* Interfacing with C - pointer problem
@ 2007-01-30 14:23 Gerd
2007-01-30 15:53 ` Frank J. Lhota
2007-01-30 21:10 ` tmoran
0 siblings, 2 replies; 5+ messages in thread
From: Gerd @ 2007-01-30 14:23 UTC (permalink / raw)
I try to call some C code, so I wrote me a simple interface, but it
does not what I expected.
It looks like this:
type LPSTR is access all String;
procedure C_Func (x : LPSTR); -- expects an address (C-pointer, 32-
bit)
pragma Import (STDCALL, C_Func, "C_Func");
procedure Q is
data : aliased String := "ABC" & Ascii.Nul;
begin
C_Func (data'unchecked_access);
end Q;
This does not work correct. What I found is, that data'Address is 32
bit and LPSTR is 64 bit.
How to manage this?
I tried a "pragma Convention (C, LPSTR);" but this gives a warning. So
what would be the right way?
Thanks in advance,
Gerd
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Interfacing with C - pointer problem
2007-01-30 14:23 Interfacing with C - pointer problem Gerd
@ 2007-01-30 15:53 ` Frank J. Lhota
2007-01-30 21:10 ` tmoran
1 sibling, 0 replies; 5+ messages in thread
From: Frank J. Lhota @ 2007-01-30 15:53 UTC (permalink / raw)
Try using the Interfaces.C.Strings facilities instead.
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Interfacing with C - pointer problem
2007-01-30 14:23 Interfacing with C - pointer problem Gerd
2007-01-30 15:53 ` Frank J. Lhota
@ 2007-01-30 21:10 ` tmoran
2007-01-31 18:10 ` Adam Beneschan
1 sibling, 1 reply; 5+ messages in thread
From: tmoran @ 2007-01-30 21:10 UTC (permalink / raw)
> type LPSTR is access all String;
>
> This does not work correct. What I found is, that data'Address is 32
> bit and LPSTR is 64 bit.
Because LPSTR points to a dynamic size string and thus needs to
carry along bounds information. A C LPSTR does not point to a dynamic
string, but instead points to a single character - the first in the
string. So the match is
type LPSTR is access Interfaces.C.Char;
procedure C_Func (x : LPSTR); -- expects an address (C-pointer, 32-bit)
and then
data : Interfaces.C.char_array := Interfaces.C.To_C("ABC");
and
C_Func (data(data'first)'unchecked_access);
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Interfacing with C - pointer problem
2007-01-30 21:10 ` tmoran
@ 2007-01-31 18:10 ` Adam Beneschan
2007-01-31 23:53 ` Jeffrey R. Carter
0 siblings, 1 reply; 5+ messages in thread
From: Adam Beneschan @ 2007-01-31 18:10 UTC (permalink / raw)
On Jan 30, 1:10 pm, tmo...@acm.org wrote:
> > type LPSTR is access all String;
>
> > This does not work correct. What I found is, that data'Address is 32
> > bit and LPSTR is 64 bit.
>
> Because LPSTR points to a dynamic size string and thus needs to
> carry along bounds information. A C LPSTR does not point to a dynamic
> string, but instead points to a single character - the first in the
> string. So the match is
> type LPSTR is access Interfaces.C.Char;
> procedure C_Func (x : LPSTR); -- expects an address (C-pointer, 32-bit)
> and then
> data : Interfaces.C.char_array := Interfaces.C.To_C("ABC");
> and
> C_Func (data(data'first)'unchecked_access);
Or perhaps better:
procedure C_Func (x : Interfaces.C.Strings.chars_ptr);
data : aliased Interfaces.C.char_array := Interfaces.C.To_C
("ABC");
C_Func (Interfaces.C.Strings.To_Chars_Ptr (data'unchecked_access));
May as well use the stuff Ada provides for this exact purpose.
-- Adam
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: Interfacing with C - pointer problem
2007-01-31 18:10 ` Adam Beneschan
@ 2007-01-31 23:53 ` Jeffrey R. Carter
0 siblings, 0 replies; 5+ messages in thread
From: Jeffrey R. Carter @ 2007-01-31 23:53 UTC (permalink / raw)
Adam Beneschan wrote:
>> type LPSTR is access Interfaces.C.Char;
>> procedure C_Func (x : LPSTR); -- expects an address (C-pointer, 32-bit)
>> and then
>> data : Interfaces.C.char_array := Interfaces.C.To_C("ABC");
>> and
>> C_Func (data(data'first)'unchecked_access);
>
> Or perhaps better:
>
> procedure C_Func (x : Interfaces.C.Strings.chars_ptr);
>
> data : aliased Interfaces.C.char_array := Interfaces.C.To_C
> ("ABC");
>
> C_Func (Interfaces.C.Strings.To_Chars_Ptr (data'unchecked_access));
>
> May as well use the stuff Ada provides for this exact purpose.
Right. Therefore, even better:
procedure C_Func (X : in Interfaces.C.Char_Array);
pragma Import (C, C_Func, ...);
Data : Interfaces.C.Char_Array := Interfaces.C.To_C ("ABC);
C_Func (X => Data);
The language passes this a a pointer to Data (Data'First). See ARM B.3
(70): "An Ada parameter of an array type with component type T, of any
mode, is passed as a t* argument to a C function, where t is the C type
corresponding to the Ada type T."
--
Jeff Carter
"Alms for an ex-leper!"
Monty Python's Life of Brian
75
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2007-01-31 23:53 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2007-01-30 14:23 Interfacing with C - pointer problem Gerd
2007-01-30 15:53 ` Frank J. Lhota
2007-01-30 21:10 ` tmoran
2007-01-31 18:10 ` Adam Beneschan
2007-01-31 23:53 ` Jeffrey R. Carter
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox