Lazarus
Programming => General => Topic started by: Goodman H__ on November 15, 2010, 12:00:20 am
-
Greetings!
As subjected,does fp support user defined variadic procedure or function like those provided in unit system,say writeln,readln?For example:
procedure printArray(ele:integer...);
begin
...
end.
test code:
printArray(1);//prints 1
printArray(1,2,3,4,5);//prints 1 2 3 4 5
Thanks in advance.
-
the closest I can think of
procedure Foo(Data: Array of Integer);
Foo([1,2,3]);
note the []
http://www.freepascal.org/docs-html/ref/refsu59.html#x136-14600011.4.5
procedure Foo(Data: Array of const);
Foo([1,2,'abc', True]);
http://www.freepascal.org/docs-html/ref/refsu60.html#x137-14700011.4.6
-
Just FYI, Read(Ln)/Write(Ln) isn't a true function. It's actually a command for the compiler, which will map to internal functions based on the type of arguments.
-
As subjected,does fp support user defined variadic procedure or function
yes
like those provided in unit system,say writeln,readln?For example:
no.
FPC provides two types of variadic functions, but the writeln/readln ones are not real procedures and behave differently.
The main variadic type is like this
procedure bla (xx:array of const);
and can only take basetypes as argument (so not e.g. records). See the manual for more details
the second type has the same (array of const) syntax, but when used in combination with cdecl, it is meant to
interface to C style variadic functions.
-
Just noticed there is a 'varargs' modifier in the fp2.6.1.Follwoing the sample code in the ref.chm,I tested in the IDE:
Function PrintF1(fmt : pchar); cdecl; varargs;
external ’c’ name ’printf’;
PrintF1(’%d %d\n’,1,1);
Actually PrintF1 is a function other than a procedure,so maybe the proper on could be:
Function PrintF1(fmt : pchar):integer; cdecl; varargs;
external ’c’ name ’printf’;
Here is the complete program:
program Project1;
{$mode objfpc}{$H+}
uses
{$IFDEF UNIX}{$IFDEF UseCThreads}
cthreads,
{$ENDIF}{$ENDIF}
Classes
{ you can add units after this };
Function PrintF1(fmt : pchar):integer; cdecl; varargs;
external 'c' name 'printf';
begin
PrintF1('%d %d\n',1,1);
readln;
end.
It compiles,but when it tried to startup,System Error:
The program can't start because c.dll missing from your computer.Try reinstalling the program to fix the problem.
I don't think there is such a c.dll in the OS.(My OS is Win7).
So could anybody figure me out what the the problem here?
BTW.Can I omit the extern 'c ' name blabla and define my own variadic functions/procedures ?
Thanks for your help in advance.
-
You have only a PrintF1 function header, but its missing its body. external 'c' is propably trying to tell that the function is found in c.dll file. Maybe you found a project in which someone made a dll with C, and then made header with pascal?
-
You have only a PrintF1 function header, but its missing its body. external 'c' is propably trying to tell that the function is found in c.dll file. Maybe you found a project in which someone made a dll with C, and then made header with pascal?
Thanks.But 'printf' isn't in the core C library?Why does one need to implement another version of printf?
-
Thanks.But 'printf' isn't in the core C library?Why does one need to implement another version of printf?
Yes it is. It resides in libc.so in *nix and msvcrt.dll on windows, you what you need to change is the {$linklib} directive to {$linklib msvcrt} instead of {$linklib c} (or you don't specify external 'c', if you do change this to external 'msvcrt' instead)
-
Thanks.But 'printf' isn't in the core C library?Why does one need to implement another version of printf?
Yes it is. It resides in libc.so in *nix and msvcrt.dll on windows, you what you need to change is the {$linklib} directive to {$linklib msvcrt} instead of {$linklib c} (or you don't specify external 'c', if you do change this to external 'msvcrt' instead)
Thank you so much.change external 'c' to external 'msvcrt' fixed the issue and the app runs finally.
But...it seems the the escape sequence '\n' does not make any sense here.
Regards,
Sam
-
But...it seems the the escape sequence '\n' does not make any sense here.
Escape characters are handled by the C compiler, not printf function (otherwise, it won't be usable in other contexts, right?). For this, use Pascal equivalent (#10), but it's better to use LineEnding constant as it's already made cross platform.
-
But...it seems the the escape sequence '\n' does not make any sense here.
Escape characters are handled by the C compiler, not printf function (otherwise, it won't be usable in other contexts, right?). For this, use Pascal equivalent (#10), but it's better to use LineEnding constant as it's already made cross platform.
Got it,exactly.Thank you.
-
Do you need this specifically for the printf function? It seems a little excessive to require an entire C runtime library to run your program for some functionality that is already served by the nice Format function: http://www.freepascal.org/docs-html/rtl/sysutils/format.html