[prev] [prev-tail] [tail] [up]

#### Declaring the external object code

##### Linking to an object file

Having declared the external function or variable that resides in an object file, you can use it as if it was defined in your own program or unit. To produce an executable, you must still link the object file in. This can be done with the {$L file.o} directive.

This will cause the linker to link in the object file file.o. On most systems, this filename is case sensitive. The object file is first searched in the current directory, and then the directories specified by the -Fo command line.

You cannot specify libraries in this way, it is for object files only.

Here we present an example. Consider that you have some assembly routine which uses the C calling convention that calculates the nth Fibonacci number:

     .text
             .align 4
     .globl Fibonacci
             .type Fibonacci,@function
     Fibonacci:
             pushl %ebp
             movl %esp,%ebp
             movl 8(%ebp),%edx
             xorl %ecx,%ecx
             xorl %eax,%eax
             movl $1,%ebx
             incl %edx
     loop:
             decl %edx
             je endloop
             movl %ecx,%eax
             addl %ebx,%eax
             movl %ebx,%ecx
             movl %eax,%ebx
             jmp loop
     endloop:
             movl %ebp,%esp
             popl %ebp
             ret

Then you can call this function with the following Pascal Program:

     Program FibonacciDemo;

     var i : longint;

     Function Fibonacci (L : longint):longint;cdecl;external;

     {$L fib.o}

     begin
       For I:=1 to 40 do
         writeln ('Fib(',i,') : ',Fibonacci (i));
     end.

With just two commands, this can be made into a program:

     as -o fib.o fib.s
     ppc386 fibo.pp

This example supposes that you have your assembler routine in fib.s, and your Pascal program in fibo.pp.

##### Linking to a library

To link your program to a library, the procedure depends on how you declared the external procedure.

In case you used the following syntax to declare your procedure:

     Procedure ProcName (Args : TPRocArgs); external 'Name';

You don’t need to take additional steps to link your file in, the compiler will do all that is needed for you. On WI N D O W S it will link to name.dll, on L I N U X and most U N I X’es your program will be linked to library libname, which can be a static or dynamic library.

In case you used

     Procedure ProcName (Args : TPRocArgs); external;

You still need to explicity link to the library. This can be done in 2 ways:

1. You can tell the compiler in the source file what library to link to using the {$LinkLib 'Name'} directive:

             {$LinkLib 'gpm'}

   This will link to the gpm library. On U N I X systems (such as L I N U X), you must not specify the extension or ’lib’ prefix of the library. The compiler takes care of that. On other systems (such as WI N D O W S, you need to specify the full name.
2. You can also tell the compiler on the command-line to link in a library: The -k option can be used for that. For example

             ppc386 -k'-lgpm' myprog.pp

   Is equivalent to the above method, and tells the linker to link to the gpm library.

As an example; consider the following program:

     program printlength;

     {$linklib c} { Case sensitive }

     { Declaration for the standard C function strlen }
     Function strlen (P : pchar) : longint; cdecl;external;

     begin
       Writeln (strlen('Programming is easy !'));
     end.

This program can be compiled with:

     ppc386  prlen.pp

Supposing, of course, that the program source resides in prlen.pp.

To use functions in C that have a variable number of arguments, you must compile your unit or program in objfpc mode or Delphi mode, and use the Array of const argument, as in the following example:

     program testaocc;

     {$mode objfpc}

     Const
       P : Pchar
         = 'example';
       F : Pchar
         = 'This %s uses printf to print numbers (%d) and strings.'#10;

     procedure printf(fm: pchar;args: array of const);cdecl;external 'c';

     begin
      printf(F,[P,123]);
     end.

The output of this program looks like this:

     This example uses printf to print numbers (123) and strings.

[prev] [prev-tail] [front] [up]