Re: [fpc-pascal] Library.StringFunction() : PChar = NO
On 16/03/2014 20:29, Fred van Stappen wrote: Many bedankt Harry . ;-) De rien Jean-Jacques-Loup-Cristophe! (not getting the name thing but wanting to enter into the spirit of the things) ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
(not getting the name thing but wanting to enter into the spirit of the things) PS : Cfr your studies in Poudlard school... :-) ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
On 15/03/2014 12:21, Fred van Stappen wrote: I thought that it was mentioned there somewhere already... If nit feel free to add it. That's what a wiki is good for afterall. ^^ Done. = http://wiki.freepascal.org/shared_library I think I've spotted a mistake in the wiki. I've adjusted the description of InLibFreeString according to Sven's previous post: And, for freeing the allocated memory, you may add this procedure in the main application : = And, for freeing the allocated memory, you may add this procedure in the library, which you can then call from your main application : and adjusted the rest of the text accordingly... Of course, please feel free to adjust. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
Date: Sun, 16 Mar 2014 10:43:17 +0100 From: reinierolislag...@gmail.com To: fpc-pascal@lists.freepascal.org Subject: Re: [fpc-pascal] Library.StringFunction() : PChar = NO On 15/03/2014 12:21, Fred van Stappen wrote: I thought that it was mentioned there somewhere already... If nit feel free to add it. That's what a wiki is good for afterall. ^^ Done. = http://wiki.freepascal.org/shared_library I think I've spotted a mistake in the wiki. I've adjusted the description of InLibFreeString according to Sven's previous post: And, for freeing the allocated memory, you may add this procedure in the main application : = And, for freeing the allocated memory, you may add this procedure in the library, which you can then call from your main application : and adjusted the rest of the text accordingly... Of course, please feel free to adjust. Many bedankt Harry . ;-) ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
Am 14.03.2014 23:46 schrieb Fred van Stappen fi...@hotmail.com: Date: Fri, 14 Mar 2014 23:11:14 +0100 From: pascaldra...@googlemail.com To: fpc-pascal@lists.freepascal.org Subject: Re: [fpc-pascal] Library.StringFunction() : PChar = NO On 14.03.2014 22:07, Fred van Stappen wrote: It's not a problem, as long as you provide an API to dispose the memory used by the returned PChar. The responsibility of calling this API is delegated to the application. Yep, with pleasure,... but how to provide an API (and what do you mean with provide an API to dispose the memory) ? = In short, what must i code to do that ? Inside your library you normally do this when creating a string result: === code begin === function InLibStringFunction: PChar; // of course declared as cdecl ;) const MyString: AnsiString = 'Hello World'; // this string could also come frome somewhere else in your library begin Result := GetMem(Length(MyString) + 1); Move(@MyString[1], Result, Length(MyString)); Result[Length(MyString)] := 0; end; === code end === Note: if your MyString is valid through the complete lifetime it could be used you can also use Result := PChar(MyString); instead, but if your string is e.g. a variable inside the function or a variable inside another function you must copy its content. If you now allocated a PChar using GetMem you add this function as well and export it from the library: === code begin === procedure InLibFreeString(aStr: PChar); begin FreeMem(aStr); end; === code end === One could of course now extend the API with additional checks. E.g. so that you know that the string was really allocated by the library and not by e.g. the program using it. But maybe the heap manager already checks this, I don't know currently. Regards, Sven Yep, Sven, excellent and hyper clear. Hum, i think that this code must go somewhere in wiki. If you agree i will add it into fpc wiki. I thought that it was mentioned there somewhere already... If nit feel free to add it. That's what a wiki is good for afterall. ^^ Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
Am 15.03.2014 00:08 schrieb Fred van Stappen fi...@hotmail.com: Note: if your MyString is valid through the complete lifetime it could be used you can also use Result := PChar(MyString); Hum, to be sure that i understand... type TStringClass = class(TObject) Name: AnsiString; does not change SomeText: AnsiString; / may change.. end; var AStringClass : TStringClass; function GetName: PChar; cdecl ; begin result := PChar(AStringClass.Name); end; function GetSomeText: PChar; cdecl ; var MyString: AnsiString ; begin MyString := AStringClass.SomeText ; Result := GetMem(Length(MyString) + 1); Move(@MyString[1], Result, Length(MyString)); Result[Length(MyString)] := 0; end; Is it OK ? You don't need the MyString variable, you can simply use AStringClass.SomeText. The variable was just for illustrations. And you should definitely document the results of which of your libraries must be freed and which must not. Additionally I would suggest to store the pointer values of the allocated PChar results (e.g. TList or specialize TFPGListPChar) so that you can use this inside your exported FreeString function to check whether this is indeed a pointer that you need to free. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
I thought that it was mentioned there somewhere already... If nit feel free to add it. That's what a wiki is good for afterall. ^^ Hum, never seen... I will add it ASAP ;-) You don't need the MyString variable, you can simply use AStringClass.SomeText. = OK And you should definitely document the results of which of your libraries must be freed and which must not. Additionally I would suggest to store the pointer values of the allocated PChar results = Yep, good idea, i will do it. One more time, tetra thanks Sven. Fred ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
I thought that it was mentioned there somewhere already... If nit feel free to add it. That's what a wiki is good for afterall. ^^ Done. = http://wiki.freepascal.org/shared_library Many thanks Sven. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
It will be the memory manager of the library who deals with the PChar result. So difficult for the main application to manage the memory used by PChar. It's not a problem, as long as you provide an API to dispose the memory used by the returned PChar. The responsibility of calling this API is delegated to the application. MyStrTest(inStr:Pchar; outStr:pChar; size:integer):integer; cdecl; var MyRealResult :string; begin MyRealResult := inStr + ' added by function '; Result := length(myRealResult); if size = result then move(OutStr[0], MyRealResult[1], result); end; Wrong usage of Move (http://www.freepascal.org/docs-html/rtl/system/move.html). First parameter is source, second is destination. So you have to swap them in above function. function testLib(InputText : string) : string ; var MyStrOut : string; MyLen : integer; begin MyLen := MyStrTest( @InputText[1],@MyStrOut[1], 0); SetLEngth(MyStrOut, mylen+1); FillChar(MyStrOut[1], MyLen+1,0); MyStrTest(@InputText[1], @MyStrOut[1], 0); result := MyStrOut ; end; Wrong usage of the MyStrTest. Here you give Size parameter of value 0, while in MyStrTest... see that last if statement? Guess yourself. Moreover, after the first call, you set the length and then filling the space with 0. The 2nd MyStrTest call doesn't differ from the first. From the code, I can guess what that good guru means. First call he just wants to get the length, therefore giving size 0. He then allocates enough storage and re-call the function, but this time he seems to have a typo. The 2nd MyStrTest call should have size parameter set to MyLen. -- View this message in context: http://free-pascal-general.1045716.n5.nabble.com/Library-StringFunction-PChar-NO-tp5718594p5718595.html Sent from the Free Pascal - General mailing list archive at Nabble.com. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
Date: Fri, 14 Mar 2014 08:20:46 -0700 From: leledumbo_c...@yahoo.co.id To: fpc-pascal@lists.freepascal.org Subject: Re: [fpc-pascal] Library.StringFunction() : PChar = NO It will be the memory manager of the library who deals with the PChar result. So difficult for the main application to manage the memory used by PChar. It's not a problem, as long as you provide an API to dispose the memory used by the returned PChar. The responsibility of calling this API is delegated to the application. MyStrTest(inStr:Pchar; outStr:pChar; size:integer):integer; cdecl; var MyRealResult :string; begin MyRealResult := inStr + ' added by function '; Result := length(myRealResult); if size = result then move(OutStr[0], MyRealResult[1], result); end; Wrong usage of Move (http://www.freepascal.org/docs-html/rtl/system/move.html). First parameter is source, second is destination. So you have to swap them in above function. function testLib(InputText : string) : string ; var MyStrOut : string; MyLen : integer; begin MyLen := MyStrTest( @InputText[1],@MyStrOut[1], 0); SetLEngth(MyStrOut, mylen+1); FillChar(MyStrOut[1], MyLen+1,0); MyStrTest(@InputText[1], @MyStrOut[1], 0); result := MyStrOut ; end; Wrong usage of the MyStrTest. Here you give Size parameter of value 0, while in MyStrTest... see that last if statement? Guess yourself. Moreover, after the first call, you set the length and then filling the space with 0. The 2nd MyStrTest call doesn't differ from the first. From the code, I can guess what that good guru means. First call he just wants to get the length, therefore giving size 0. He then allocates enough storage and re-call the function, but this time he seems to have a typo. The 2nd MyStrTest call should have size parameter set to MyLen. @ leledumbo, like always = brilliant = Tetras * Megas thanks. ;-) ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
It's not a problem, as long as you provide an API to dispose the memory used by the returned PChar. The responsibility of calling this API is delegated to the application. Yep, with pleasure,... but how to provide an API (and what do you mean with provide an API to dispose the memory) ? = In short, what must i code to do that ? Re-Many thanks. Fred ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
On 14.03.2014 22:07, Fred van Stappen wrote: It's not a problem, as long as you provide an API to dispose the memory used by the returned PChar. The responsibility of calling this API is delegated to the application. Yep, with pleasure,... but how to provide an API (and what do you mean with provide an API to dispose the memory) ? = In short, what must i code to do that ? Inside your library you normally do this when creating a string result: === code begin === function InLibStringFunction: PChar; // of course declared as cdecl ;) const MyString: AnsiString = 'Hello World'; // this string could also come frome somewhere else in your library begin Result := GetMem(Length(MyString) + 1); Move(@MyString[1], Result, Length(MyString)); Result[Length(MyString)] := 0; end; === code end === Note: if your MyString is valid through the complete lifetime it could be used you can also use Result := PChar(MyString); instead, but if your string is e.g. a variable inside the function or a variable inside another function you must copy its content. If you now allocated a PChar using GetMem you add this function as well and export it from the library: === code begin === procedure InLibFreeString(aStr: PChar); begin FreeMem(aStr); end; === code end === One could of course now extend the API with additional checks. E.g. so that you know that the string was really allocated by the library and not by e.g. the program using it. But maybe the heap manager already checks this, I don't know currently. Regards, Sven ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
Date: Fri, 14 Mar 2014 23:11:14 +0100 From: pascaldra...@googlemail.com To: fpc-pascal@lists.freepascal.org Subject: Re: [fpc-pascal] Library.StringFunction() : PChar = NO On 14.03.2014 22:07, Fred van Stappen wrote: It's not a problem, as long as you provide an API to dispose the memory used by the returned PChar. The responsibility of calling this API is delegated to the application. Yep, with pleasure,... but how to provide an API (and what do you mean with provide an API to dispose the memory) ? = In short, what must i code to do that ? Inside your library you normally do this when creating a string result: === code begin === function InLibStringFunction: PChar; // of course declared as cdecl ;) const MyString: AnsiString = 'Hello World'; // this string could also come frome somewhere else in your library begin Result := GetMem(Length(MyString) + 1); Move(@MyString[1], Result, Length(MyString)); Result[Length(MyString)] := 0; end; === code end === Note: if your MyString is valid through the complete lifetime it could be used you can also use Result := PChar(MyString); instead, but if your string is e.g. a variable inside the function or a variable inside another function you must copy its content. If you now allocated a PChar using GetMem you add this function as well and export it from the library: === code begin === procedure InLibFreeString(aStr: PChar); begin FreeMem(aStr); end; === code end === One could of course now extend the API with additional checks. E.g. so that you know that the string was really allocated by the library and not by e.g. the program using it. But maybe the heap manager already checks this, I don't know currently. Regards, Sven Yep, Sven, excellent and hyper clear. Hum, i think that this code must go somewhere in wiki. If you agree i will add it into fpc wiki. Many thanks. Fred. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Re: [fpc-pascal] Library.StringFunction() : PChar = NO
Note: if your MyString is valid through the complete lifetime it could be used you can also use Result := PChar(MyString); Hum, to be sure that i understand... type TStringClass = class(TObject) Name: AnsiString; does not change SomeText: AnsiString; / may change.. end; var AStringClass : TStringClass; function GetName: PChar; cdecl ; begin result := PChar(AStringClass.Name); end; function GetSomeText: PChar; cdecl ; var MyString: AnsiString ; begin MyString := AStringClass.SomeText ; Result := GetMem(Length(MyString) + 1); Move(@MyString[1], Result, Length(MyString)); Result[Length(MyString)] := 0; end; Is it OK ? Thanks. ___ fpc-pascal maillist - fpc-pascal@lists.freepascal.org http://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal