My thanks for confirming that writeln is not implemented using C's printf function (I can't remember where I got that idea) and that gpc's writeln can send all 256 characters (absolutely necessary to handle binary time as a string).
On reflection I realize I have misstated our problem. But I think I also have a work-around for it.
The issue is that the supplied library returns the time as a 32 bit binary value. The problem is essentially how to coerce the 32 bits into a corresponding 4 character gpc string. (BTW, they are the first 4 bytes of every message sent by our application).
I had hoped that the coercion (effectively a type cast) would be easy to accomplish within Pascal. I then thought about variant records but that did not seem feasible. I have since realized that the conversion could be done where we define the interface to the external routine. In the Pascal function definition use a 4 character fixed length string for the time field and have the linker map that string to the corresponding 32 bit value field used by the library (probably by using pass-by-address, possibly pass-by-value). Not a pure Pascal approach but a practical one - as long as you are well aware of the pitfalls. (In the "pure" approach the Pascal interface parameter would be a 32 bit unsigned value that gets converted/mapped by Pascal to the corresponding 4 byte string).
Anyone have any thoughts on this? Have I have missed a simpler approach?
John.
-----Original Message----- From: gpc-owner@gnu.de [mailto:gpc-owner@gnu.de] On Behalf Of Frank Heckenbach Sent: September 3, 2010 05:16 PM To: gpc@gnu.de Subject: Re: Null characters (& string
Morton, John wrote:
We have encountered an unexpected implementation issue with gpc, one that probably affects all languages implemented using C/C++: The mapping of Pascal writeln (etc.) statements to "equivalent" C/C++
string
handling code.
Others have replied already, but I can confirm that GPC does not use printf etc. internally to implement WriteLn, if that's what you mean.
Stated more generally, is there a pure gpc Pascal way to send ("writeln") strings that can contain any/all of the 256 8 bit
characters
(especially the null) - an approach that does not require retyping our string definitions?
Of course, any such way is not pure Pascal in the sense of ISO Pascal or so. Text files (WriteLn) are not really meant for binary data, though it works with GPC, and is as portable as GPC is, and probably works with some other compilers as well. The official Pascal way would be a "file of Char" (though ISO Pascal doesn't even guarantee that the NUL character is part of the character set), where you'd need to read/write every character individually.
Frank
Morton, John wrote:
My thanks for confirming that writeln is not implemented using C's printf function (I can't remember where I got that idea) and that gpc's writeln can send all 256 characters (absolutely necessary to handle binary time as a string).
On reflection I realize I have misstated our problem. But I think I also have a work-around for it.
The issue is that the supplied library returns the time as a 32 bit binary value. The problem is essentially how to coerce the 32 bits into a corresponding 4 character gpc string. (BTW, they are the first 4 bytes of every message sent by our application).
I had hoped that the coercion (effectively a type cast) would be easy to accomplish within Pascal. I then thought about variant records but that did not seem feasible. I have since realized that the conversion could be done where we define the interface to the external routine. In the Pascal function definition use a 4 character fixed length string for the time field and have the linker map that string to the corresponding 32 bit value field used by the library (probably by using pass-by-address, possibly pass-by-value). Not a pure Pascal approach but a practical one - as long as you are well aware of the pitfalls. (In the "pure" approach the Pascal interface parameter would be a 32 bit unsigned value that gets converted/mapped by Pascal to the corresponding 4 byte string).
The only "pure" Pascal approach would be converting the value to single bytes using "div"/"mod" (GPC also supports bitwise "and" and "shl"/"shr") and then to characters using "Chr". If it's not time-critical, this might actually be worth considering, since it avoids endianness issues.
With GPC, also type-casting should work. Something like this:
program Foo;
type Card32 = Cardinal attribute (Size = 32); Char4 = array [1 .. 4] of Char;
var a: Card32; b: Char4;
begin b := Char4 (a); a := Card32 (b); end.
Variant records are sometimes abused(!) for this purpose, but I don't recommend it.
Frank