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

Urbansound urbansound at sbcglobal.net
Tue Aug 2 19:42:36 CEST 2005


Thanks Matt.

See replies within the body please.

----- Original Message ----- =

From: "Matt Emson" <memsom at interalpha.co.uk>
To: "Urbansound" <urbansound at sbcglobal.net>; "FPC-Pascal users discussions" =

<fpc-pascal at lists.freepascal.org>
Sent: Tuesday, August 02, 2005 11:26 AM
Subject: Re: [fpc-pascal] Extended float to single and pchar types


>> 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?

Tried all three and results are the same always, (which I find odd, =

considering mangling)

>
>> 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 :=3D 'Test data';
>  SetLength(s, Length(s));
>  SendMessage(listbox, LB_ADDSTRING, 0, longint(@(s[1])));

Working only by virtue of the non error checking method using =

Str(bid_price:5:3,s);
See example at bottom.

> 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.

Single thread, confirmed

>> 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.

Apparently that is a problem when the float is in a callback.

>
> e.g.
>
> var
>  f: single;
>  d: double;
>  e: extended;
> begin
>  f :=3D 10.01;
>  d :=3D 10.01;
>  e :=3D 10.01;
>
>  messagebox(0, PChar(FloatToStr( .. ), 0); // replace '..' with f, d or e
> end;

Crashes when incorporated into the callback.

>> 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 :=3D 123.45678; //this will round
>  s :=3D format('%3.3f', [f]); //think sprintf
> end;

Crashes same when f holds the value returned in the callback.

>> 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

Any ansistring causes a hard crash.

Below will run without crashing, but again the string length is even cast a=
t =

9, the max expected and equal white space being seed to the string first. =

You can see the image "output.jpg" attached, showing the residual string =

data, right of the values.  These are stock market symbols and their relate=
d =

prices being quoted, which are the content coming back from the live API.

Type shortstring =3D string[9];
var
    bid_price : extended; //or double, or single =3D same result
    s : shortstring;

begin
     SendMessage(listbox, LB_ADDSTRING, 0,
        longint(Get_secsym(quote)));
    // quote data may range nn.nnn to nnnnn.nnn
     bid_price :=3D Get_l1_BidPrice(quote);
     //s:=3DFloatToStr(bid_price);           //crashes 207
     s:=3D'         ';                                    // 9 bytes white =

space
     Str(bid_price:5:3,s);                      //convert+ 5 places, 3 =

decimal  =3D 6
     SetLength(s, Length(s));
     SendMessage(listbox, LB_ADDSTRING, 0, longint(@(s[1])));
end; =

-------------- next part --------------
A non-text attachment was scrubbed...
Name: output.JPG
Type: image/jpeg
Size: 59050 bytes
Desc: not available
Url : http://lists.freepascal.org/lists/fpc-pascal/attachments/20050802/f23=
a001b/output.jpeg


More information about the fpc-pascal mailing list