Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2005-08

Extended float to single and pchar types

5 messages · 2 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Urbansound

Hi,

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

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';
The end result is to allow a usage in win32 as ...
SendMessage(listbox, LB_ADDSTRING, 0, longint(Pchar(s)));

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.

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

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.

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?

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.

Thanks as always.

Mike

Matt Emson
to Urbansound
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?

Show quoted text 6 lines
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

Show quoted text 8 lines
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

Urbansound
to Matt Emson

Thanks Matt.

See replies within the body please.

Earlier message 160 lines
----- Original Message ----- From: "Matt Emson" To: "Urbansound" ; "FPC-Pascal users discussions" 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;
Urbansound
to Matt Emson: Are you sure it is stdcall? Quite often it's the calling convention that messes up the…

----- Original Message -----

Earlier message 21 lines
From: "Matt Emson" To: "Urbansound" ; "FPC-Pascal users discussions" Sent: Tuesday, August 02, 2005 11:26 AM Subject: Re: [fpc-pascal] Extended float to single and pchar types > 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? > Well... I was sure until it was pointed out that I needed to change ALL of the declarations, not just the one I was accessing, which means that other stdcall declarations were likely stepping on the stack or heap, while I was focused only on the one call I changed. DOAH! You were correct in your observation. Thank you Matt. Mike
Urbansound
to Urbansound: Thanks Matt. See replies within the body please. ----- Original Message ----- From: "Matt…

Please ignore this. It is an FPC mailing list error, repeated from August

Earlier message 190 lines
----- Original Message ----- From: "Urbansound" To: Cc: "Matt Emson" Sent: Tuesday, August 02, 2005 1:41 PM Subject: Re: [fpc-pascal] Extended float to single and pchar types > Thanks Matt. > > See replies within the body please. > > ----- Original Message ----- > From: "Matt Emson" > To: "Urbansound" ; "FPC-Pascal users > discussions" > > 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; > -------------------------------------------------------------------------------- > _______________________________________________ > fpc-pascal maillist - > http://lists.freepascal.org/mailman/listinfo/fpc-pascal >