[fpc-pascal] Extended float to single and pchar types

Matt Emson memsom at interalpha.co.uk
Tue Aug 2 17:26:23 CEST 2005


> Hi,
>
> I have a stdcall reference to a c based dll. called target.dll
> In c the setup is ...

Are you sure it is stdcall? Quite often it's the calling convention that
messes up the calling of a C DLL. Could it be safecall or cdecl? Which
compiler made the DLL?

> float Get_l1_BidPriceSingle(void* p);
>
> The Pascal reference is...
>
> function Get_l1_BidPrice(p : pointer) : single;
> stdcall; external 'target.dll' name 'Get_l1_BidPrice';

Which all looks okay.

> The end result is to allow a usage in win32 as ...
> SendMessage(listbox, LB_ADDSTRING, 0, longint(Pchar(s)));

Hmmm.. this is not a good idea if 's' is of type string. If 's' is a string
(AnsiString or whatever) you should probably call SetLength on it, and I'd
also advise passing a pointer to the first char too, rather relying on the
cast.

E.g.

  s := 'Test data';
  SetLength(s, Length(s));
  SendMessage(listbox, LB_ADDSTRING, 0, longint(@(s[1])));

That probably has more chance of working, but still assumes you are not
crossing process boundaries. If threads are involved, it's not going to
work.


> The c reference is  a 'Single' float, but each time I make refernece to
data
> conversion, errors tell me that the reference to the call is returning a
10
> bit "Extended" float which fails, appearing to be a default autotype
> conversions to an extended 10 byte float, in fpc.

If it is a "reference", it should probably be a pointer. Is the C function
really returning the resultant by value, or by reference?

> Converted data as an "Ansistring" seems to fail any type of conversion, as
a
> runtime 207 crash.

Convert how? FloatToStr should handle any floating point type.

e.g.

var
  f: single;
  d: double;
  e: extended;
begin
  f := 10.01;
  d := 10.01;
  e := 10.01;

  messagebox(0, PChar(FloatToStr( .. ), 0); // replace '..' with f, d or e
end;


> If I store Str conversions to a "shortstring", I can format the fp and
> convert it to a fixed decimal rounded output, xxx.yyy, but using length()
> direct or pointer access, still pulls the 0 byte and extra characters of
the
> string into any other converted output, requiring array managment and
> parsing.

var
   s: string;
   f: single;
begin
  f := 123.45678; //this will round
  s := format('%3.3f', [f]); //think sprintf
end;

> Is there a way to take an "extended" FP and covert it ultimately to a
Pchar
> that would allow messaging to win32 list boxes or similar to a litteral
> equivelent behaviour, without having to run through all the symantics of
> array management?
>
> OR
>
> Can one circumvent the auto-typing to extended, so that single or double
> would behave to conversion methods like FloatToStr() that I could then
type
> over to pchar and serve the same purpose?

Surely you could just use an extended and then cast it? So long as it is
possible to store the value in the variable you wish to, it'll work.

> Clearly I'm not yet comfortable with string manipulation in Pascal, so an
> example would go a long way toward getting me to where I can do the work
> myself.

Well, it's an awful lot simpler that C until you have to interact with C API
calls!!

M





More information about the fpc-pascal mailing list