Hi Kevin
Your program is doing exactly what you told it to do You defined a CString which begins byte1 = H, byte 2 = e, etc., disabled error detection with {$X+} and then called it a string: first 4 bytes is capacity, next 4 bytes current length, then the string bytes
As far as I know the only time you'll need {$X+} is for a wrapper around function setlength() ( remember to also use {$X-} )
So take out the {$X+} and use functions CString2String and String2CString where you need them.
Also noticed the function twine in the interface doesn't match function twine in the implementation. It didn't trigger an error message but I don't know if that's a bug or a extended pascal "extension".
In the rewrite which follows couldn't return a CString so changed it to a string. Think this is a language restriction. ( However it could be me ) Type string25 appears twice becaue the implementation section din't see it in the interface section. I think that's a bug.
Hope this helps Russ russwhit@mind.net
{---------------------------------------------------------} Module FOO interface;
Export FOO = (twine); type String25 = String(25); function twine( foobar: CString ): String25;
end. {interface}
Module FOO implementation; type String25 = String(25);
function twine( foobar: CString ): String25; var local : string25 value 'oops'; begin writeln('In Module: ', CString2String( foobar)); writestr(local, CString2String( foobar), chr(0)); writeln('In Module(2): ', local); twine := local; end; {twine} end.
{-----------------------------------------------------} program KFoss( input, output ); import foo;
var foobaz : CString; begin foobaz := "Hello there."; writeln('Main Loop: ', CString2String( foobaz)); writeln('After Module: ', twine( foobaz )); end.
----------
From: Kevin A. Foss kfoss@mint.net To: gpc@hut.fi Subject: CStrings getting corrupted on return from Modules. Date: Sunday, August 29, 1999 9:36 AM
Hi, I'm having a problem where strings seem to get corrupted when they are returned as a CString from a module.
It is certainly possible that this is a problem on my end as I may be illegally modifying strings in someway, as I am mixing EP string() type variables and CStrings, as well as using {$x+} features. Is there a good guide on how to use/convert the different string types? I know this code used to work with older versions of gpc -- trying to move my Pascal code from OS/2 to Linux (more on that in next message) caused me to find this.
Anyways here is a sample run of the code included below:
Main Loop: Hello there. In Module: Hello there. In Module(2): Hello there. After Module: x)@xY@ere.
I replaced the high ASCII with an x to avoid mailer mangling.
I'm using the latest version of gpc (compiled for gcc-2.95) available as a Debian package. It claims to be 19990610, but someone said that the latest snapshot misreports? -- so I think it is the latest version. If I'm wrong, sorry.
The code follows below: foo.pas:
Module FOO Interface;
Export FOO = (twine);
function twine(foobar : CString): CString;
end. { Interface }
Module FOO Implementation;
type String25 = String(25); function twine; {$x+} var local : String25;
begin writeln('In Module: ', foobar); writestr(local, foobar, chr(0)); writeln('In Module(2): ', local); twine := local; end; { twine }
end. { FOO }
test.pas: program test(input, output);
import foo;
var foobaz : Cstring;
begin {$x+} foobaz := "Hello there."; writeln('Main Loop: ', foobaz); writeln('After Module: ', twine(foobaz)); end.
Thanks,
-Kevin
Kevin A. Foss ---- kfoss@mint.net
Russ Whitaker wrote:
Type string25 appears twice becaue the implementation section din't see it in the interface section. I think that's a bug.
Yes (kevin13.pas).
Thanks,
Peter
On Sun, Aug 29, 1999 at 11:41:42PM -0700, Russ Whitaker wrote:
Hello,
Your program is doing exactly what you told it to do You defined a CString which begins byte1 = H, byte 2 = e, etc., disabled error detection with {$X+} and then called it a string: first 4 bytes is capacity, next 4 bytes current length, then the string bytes
[...]
So take out the {$X+} and use functions CString2String and String2CString where you need them.
Yes, this seems to be exactly what I need. Like I said in my original message it was just a case of me misunderstanding how the different string types cooperate -- and I mistakenly thought that straight CString := String assignments worked in a previous gpc version.
Also the reason I was really using {$x+} is so I could do unaltered writelns, e.g. you can writeln a CString without passing it through CString2String. The error message when you do this more or less suggests {$x+}, so I just plugged it in there. The side effect as you point out was that it also wasn't telling me that I was mangling my strings.
Also is {$x+} really error detection off? I thought it was for eXtended syntax? Regardless, it let me throughly &#*@ up my strings.
Is there a guide to all of the different String functions for conversion and what not?
Also noticed the function twine in the interface doesn't match function twine in the implementation. It didn't trigger an error message but I don't know if that's a bug or a extended pascal "extension".
Um, I thought it was exactly how EP was supposed to work, you define all of the argument and return types in the interface and just give the function name in the implementation.
In the rewrite which follows couldn't return a CString so changed it to a string. Think this is a language restriction. ( However it could be me )
This is weird, my own rewrite of the interface works fine returning CStrings, had no problem. You have to fix the 'twine :=' line in the module and the writeln in the main program.
Thanks for all the help,
-Kevin
Kevin A. Foss wrote:
Also is {$x+} really error detection off?
No, it's eXtended syntax: CStrings, pointer arithmetics, etc.
Is there a guide to all of the different String functions for conversion and what not?
Not yet, sorry. Writers welcome.
Also noticed the function twine in the interface doesn't match function twine in the implementation. It didn't trigger an error message but I don't know if that's a bug or a extended pascal "extension".
Um, I thought it was exactly how EP was supposed to work, you define all of the argument and return types in the interface and just give the function name in the implementation.
Indeed.
In the rewrite which follows couldn't return a CString so changed it to a string. Think this is a language restriction. ( However it could be me )
This is weird, my own rewrite of the interface works fine returning CStrings, had no problem. You have to fix the 'twine :=' line in the module and the writeln in the main program.
If you return a CString you must keep in mind that it is a pointer to some array. You must not let it point to a local variable that will vanish when the function exits. You can allocate memory for that variable using GetMem, but then you must remember to FreeMem (or Dispose) it once the function result is not needed any more. In any case, CStrings are a kludge; better avoid them. ;-)
Peter