Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2001-06

linking pascal objects/units into C

10 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Oliver Graf

Hi!

We have a pretty old pascal project (delphi 1 on win95 -- already ported) and we need to interface it with various script languages (python, perl, etc.). So we need to link the pascal units to some C interfacing code for those script languages.

Has anyone done this before and can provide us with some hints how to archive this (i.e. creating a C header for the unit, calling conventions, argument passing)?

Target system is linux.

Regards,
Oliver.

Fernando Lozano
to Oliver Graf

Hi Oliver,

We have a pretty old pascal project (delphi 1 on win95 -- already ported) and we need to interface it with various script languages (python, perl, etc.). So we need to link the pascal units to some C interfacing code for those script languages.

This is not hard at all, as FPC can use C calling conventions and can gennerate standard linux dynamic libraries (*.so). You just have to be carefull about different data types supported by each language, and how to provide the "external" declarations for C and Pascal. Hint: never use pascal Strings, use pchar and ansistrings. I guess integers and real are compatible.

Other hint: of your library use standard pascal procedures (like writeln) you'll have to link the C programs against the pascal system unit, and I don't know how to do that. But if you rewrite everything to use Unix system calls (the unit linux) everything'll be fine. (please anyone tell me if I am wrong).

I am sending a very simple sample where I build a dynamic library (lteste.pas) and call it both from a pascal program (teste2.pas) and a C program (teste3.pas). I'm sorry, the comments are on portuguese, but they are so simple you'll understand anyway.

[]s, Fernando Lozano

Fernando Lozano
to Oliver Graf: Hi myself! This now breaks down to: which fpc runtime libs do I need to link (basically)…

Oliver,

This now breaks down to: which fpc runtime libs do I need to link (basically) to a C programm which uses a pascal unit? I've added rtl/libsyslinux.a and rtl/libsysutils.a, but _haltproc and INITFINAL (used in libsyslinux.a) are still missing.

I solved the problem by not creating a unit but instead creating a library. You can create a Unit including only external declarations to make use of the library easier.

[]s, Fernando Lozano

Peter Vreman
Show quoted text 12 lines
Hi! We have a pretty old pascal project (delphi 1 on win95 -- already ported) and we need to interface it with various script languages (python, perl, etc.). So we need to link the pascal units to some C interfacing code for those script languages. Has anyone done this before and can provide us with some hints how to archive this (i.e. creating a C header for the unit, calling conventions, argument passing)? Target system is linux.

Using the latest snapshots (both 1.0.5 or 1.1 support it) it is possible to create a shared library the same way as creating a dll under windows. This library can then be linked in your C program

Oliver Graf
to Oliver Graf: Hi! We have a pretty old pascal project (delphi 1 on win95 -- already ported) and we need…

Hi myself!

Oliver Graf wrote 10 lines
We have a pretty old pascal project (delphi 1 on win95 -- already ported) and we need to interface it with various script languages (python, perl, etc.). So we need to link the pascal units to some C interfacing code for those script languages. Has anyone done this before and can provide us with some hints how to archive this (i.e. creating a C header for the unit, calling conventions, argument passing)? Target system is linux.

This now breaks down to: which fpc runtime libs do I need to link (basically) to a C programm which uses a pascal unit? I've added rtl/libsyslinux.a and rtl/libsysutils.a, but _haltproc and INITFINAL (used in libsyslinux.a) are still missing.

example:

compile unit with 'fpc test'

try to compile C with 'gcc test.c test.o /usr/lib/fpc/1.0.4/units/linux/rtl/libsysutils.a /usr/lib/fpc/1.0.4/units/linux/rtl/libsyslinux.a -o doittest'

Any hints?

Oliver.

-+-+-+ test.pas
unit test;
interface
procedure doit(i : integer); cdecl;
implementation
procedure doit(i : integer); cdecl; export;
begin
   writeln('Hello World!');
   writeln(i);
   writeln();
end; { doit }
end.
-+-+-+

-+-+-+ test.h
void doit(int i);
-+-+-+

-+-+-+ test.c
#include <stdio.h>
#include "test.h"

int main(int argc, char **argv) {

  doit(1);
  return 0;

}
-+-+-+

Peter Vreman
to Oliver Graf
you wrote 28 lines
Hi myself! On Mon, Jun 18, 2001 at 12:43:50PM +0200, Oliver Graf wrote: > We have a pretty old pascal project (delphi 1 on win95 -- already > ported) and we need to interface it with various script languages > (python, perl, etc.). So we need to link the pascal units to some > C interfacing code for those script languages. > > Has anyone done this before and can provide us with some hints how > to archive this (i.e. creating a C header for the unit, calling > conventions, argument passing)? > > Target system is linux. This now breaks down to: which fpc runtime libs do I need to link (basically) to a C programm which uses a pascal unit? I've added rtl/libsyslinux.a and rtl/libsysutils.a, but _haltproc and INITFINAL (used in libsyslinux.a) are still missing. example: compile unit with 'fpc test' try to compile C with 'gcc test.c test.o /usr/lib/fpc/1.0.4/units/linux/rtl/libsysutils.a /usr/lib/fpc/1.0.4/units/linux/rtl/libsyslinux.a -o doittest' Any hints?

You need to create a library. The library will include all the required units.

library test;
procedure doit(i : integer); cdecl; export;
begin
    writeln('Hello World!');
    writeln(i);
    writeln();
end; { doit }
exports
   doit;
end.

This will create a file libtest.so. Copy this file into /usr/lib or any other path searched by ld. Then run ldconfig to update the ld.cache file. And finally you can compile test.c and link the library with:

gcc -o test test.c -ltest

Peter

Peter Vreman
Show quoted text 10 lines
Hi Peter, > Using the latest snapshots (both 1.0.5 or 1.1 support it) it is possible to create a > shared library the same way as creating a dll under windows. This library can then be > linked in your C program I did this without using the latest snapshots, that is, using the (old) binary distribution of 1.0.4 on the free pascal site.

But the unit initialization/finalization code is then not run. So a writeln() from the library doesn't work

Oliver Graf
to Peter Vreman: You need to create a library. The library will include all the required units. library…

Hi!

Peter Vreman wrote
You need to create a library. The library will include all the required units.

Ok, I did this.

This will create a file libtest.so. Copy this file into /usr/lib or any other path searched by ld. Then run ldconfig to update the ld.cache file. And finally you can compile test.c and link the library with:

I did set LD_LIBRARY_PATH and use -L. in the gcc call.

gcc -o test test.c -ltest

Yep, so linking works... but... no output is given by the pascal procedure. If I do some output in C after the pascal call, it also is not executed. The binary simply returns to commandline and the exit code of the programm is 103 (is this something pascalisch?).

If I use Fernandos example, it works indeed! But he moves output to C.

I could do that, but I don't know if our project uses pascal libraries internally, I just have an API to work with and I'm the lucky one who has to write the perl and the python modules... Oh, one thing I know: it is completely object oriented inside! Is this also a problem (there are some object libs in the rtl path)?

But I will talk back to the pascal developer, perhaps he only uses self-written stuff...

But on the other hand: There must be a way to link the pascal stuff into my C stuff, or not?

Thanxx for the quick help!

Regards,
Oliver.