[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 := '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 := 10.01;
>  d := 10.01;
>  e := 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 := 123.45678; //this will round
>  s := 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 at 
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 related 
prices being quoted, which are the content coming back from the live API.

Type shortstring = string[9];
var
    bid_price : extended; //or double, or single = 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 := Get_l1_BidPrice(quote);
     //s:=FloatToStr(bid_price);           //crashes 207
     s:='         ';                                    // 9 bytes white 
space
     Str(bid_price:5:3,s);                      //convert+ 5 places, 3 
decimal  = 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/pipermail/fpc-pascal/attachments/20050802/f23a001b/attachment.jpe>


More information about the fpc-pascal mailing list