Difference between revisions of "Creating bindings for C libraries"

From Lazarus wiki
Jump to navigationJump to search
Line 27: Line 27:
 
The C header files .h describes the interface of a C library. They are normally not provided with the library. You have to get the sources or the development package of the library. For example the C header files of the gtk libraries are in the package gtk+-devel.
 
The C header files .h describes the interface of a C library. They are normally not provided with the library. You have to get the sources or the development package of the library. For example the C header files of the gtk libraries are in the package gtk+-devel.
  
==Example: MPICH2==
+
===Example: MPICH2===
  
 
Download the mpich2-1.0.3.tar.gz from http://www-unix.mcs.anl.gov/mpi/mpich2/ and unpack them. The .h files are under mpich2-1.0.3/src/include.
 
Download the mpich2-1.0.3.tar.gz from http://www-unix.mcs.anl.gov/mpi/mpich2/ and unpack them. The .h files are under mpich2-1.0.3/src/include.
Line 36: Line 36:
 
Copy the .h files.
 
Copy the .h files.
  
==Example: MPICH2==
+
===Example: MPICH2===
  
 
The h2p directory will be used for the pascal files.
 
The h2p directory will be used for the pascal files.
Line 48: Line 48:
 
Open the h2pas wizard: "Tools -> h2pas". This will open a window. You can switch between this window and the other IDE windows. Your last h2pas project will be loaded automatically. To create a new project click on "Settings -> New/Clear settings". Then click on the bottom button "Save settings" and choose a filename.
 
Open the h2pas wizard: "Tools -> h2pas". This will open a window. You can switch between this window and the other IDE windows. Your last h2pas project will be loaded automatically. To create a new project click on "Settings -> New/Clear settings". Then click on the bottom button "Save settings" and choose a filename.
  
==Example: MPICH2==
+
===Example: MPICH2===
  
 
Click on "Settings -> New/Clear settings". Then click on the bottom button "Save settings" and save it as h2p/mpi2.h2p.
 
Click on "Settings -> New/Clear settings". Then click on the bottom button "Save settings" and save it as h2p/mpi2.h2p.
Line 56: Line 56:
 
In the "C header files" page you can add/delete the .h files. You can enable/disable .h files to convert only part of the files.
 
In the "C header files" page you can add/delete the .h files. You can enable/disable .h files to convert only part of the files.
  
==Example: MPICH2==
+
===Example: MPICH2===
  
 
Click on "C header files -> Add .h files ..." and select "mpi.h". It will be enabled automatically.
 
Click on "C header files -> Add .h files ..." and select "mpi.h". It will be enabled automatically.
Line 64: Line 64:
 
Under "h2pas Options" you can set the parameters for the h2pas program.
 
Under "h2pas Options" you can set the parameters for the h2pas program.
  
==Example: MPICH2==
+
===Example: MPICH2===
  
 
*Enable -e, -D, -p, -w and disable all others.
 
*Enable -e, -D, -p, -w and disable all others.
Line 73: Line 73:
 
=Run the wizard=
 
=Run the wizard=
  
Click on the bottom button "Run converter and h2pas".
+
Click on the bottom button "Run h2pas".
This will copy the example.h file to a temporary example.tmp.h file and run the tools listed under "Before h2pas". Then it runs h2pas.
+
This will copy the <example>.h file to a temporary <example>.tmp.h file and run the tools listed under "Before h2pas". Then it runs h2pas to convert the <example>.tmp.h into <example>.inc or <example>.pas or whatever output extension you setup on the h2pas page.
  
If h2pas finds a sytax error, the IDE will open the example.tmp.h file and jumps to the error line. h2pas often only reports 'syntax error'. See below for a list of common problems and possible fixes.
+
If h2pas finds a syntax error, the IDE will open the example.tmp.h file and jumps to the error line. h2pas often only reports 'syntax error'. See below for a list of common problems and possible fixes.
  
==Example: MPICH2==
+
===Example: MPICH2===
  
 
The h2pas wizard already contains all tools to convert all the specials of this header file, so it runs without errors.
 
The h2pas wizard already contains all tools to convert all the specials of this header file, so it runs without errors.
Line 86: Line 86:
 
Here is a list of common C structures, not recognized by h2pas and how to fix them:
 
Here is a list of common C structures, not recognized by h2pas and how to fix them:
  
==extern "C"==
+
==h2pas problem: extern "C"==
  
 
Some header files contain the C++ namespace block:
 
Some header files contain the C++ namespace block:
Line 99: Line 99:
 
Fix: Add the '''Remove C++ 'extern "C"' lines''' to the '''before h2pas''' tools.
 
Fix: Add the '''Remove C++ 'extern "C"' lines''' to the '''before h2pas''' tools.
  
==empty macro==
+
==h2pas problem: Empty macro==
  
 
Some header files contain empty macros used for further extensions:
 
Some header files contain empty macros used for further extensions:
Line 106: Line 106:
 
Fix: Add the '''Remove empty C macros''' to the '''before h2pas''' tools.
 
Fix: Add the '''Remove empty C macros''' to the '''before h2pas''' tools.
  
==Implicit array types==
+
==h2pas problem: Implicit array types==
  
 
C allows implicit arrays in parameter types. For example:
 
C allows implicit arrays in parameter types. For example:
Line 115: Line 115:
 
Fix: Add the '''Replace [] with *''' to the '''before h2pas''' tools.
 
Fix: Add the '''Replace [] with *''' to the '''before h2pas''' tools.
  
==Makros for 0 pointers==
+
==h2pas problem: Makros for 0 pointers==
  
 
Some header files contain typed 0 pointers:
 
Some header files contain typed 0 pointers:
Line 124: Line 124:
 
=Test compilation and add tools to beautify the output=
 
=Test compilation and add tools to beautify the output=
  
When h2pas runs without errors it has created a pascal file or an include file.
+
When h2pas runs without errors it has created a pascal file. The -i switch defines if it is a unit or an include file.
 +
The next step is test compilation. Setup up a test project that uses the new pascal source.
 +
Then use the 'Run h2pas and compile' button in the h2pas wizard.
  
ToDo: automatically compile the new file and jump to errors
+
===Example: MPICH2==
 +
 
 +
Create a new project with Project -> New Project -> Program.
 +
Save it a '''mpihelloworld'''.
 +
Change the code to
 +
 
 +
<pre>
 +
program MPIHelloWorld;
 +
 
 +
{$mode objfpc}{$H+}
 +
{$linklib mpich}
 +
{$linklib rt}
 +
 
 +
uses
 +
  {$IFDEF UNIX}pthreads{$ENDIF}, MPI;
 +
 
 +
begin
 +
  MPI_Init(@argc, @argv);
 +
  writeln('Hello, world.');
 +
  MPI_Finalize;
 +
end.
 +
</pre>
 +
 
 +
Add the h2p/mpi.pas to the project. Project -> Add editor file to project.
  
ToDo: implement a GUI to setup the compilation
 
  
 
==Unit name contains the file path==
 
==Unit name contains the file path==

Revision as of 10:39, 23 September 2006

Overview

This page describes how to create pascal bindings for C libraries. Normally Pascal can not use C libraries directly. You have to create for every C function, type, variable a pascal translation. There is the h2pas tool, which can automatically translate many common C things. And there is a GUI for Lazarus using h2pas and other tools to automate the creation, so that if the bindings need to be updated you don't have to restart all over.

Work flow

  • Fetch the C header files you want to translate.
  • Create a working directory and give your bindings a name
  • Create a new h2pas project with the h2pas wizard.
  • add the .h files to the project
  • setup the h2pas options
  • run the wizard
  • fix errors by adding text tools and run the wizard again
  • when h2pas runs without errors, test compilation and add optional tools to beautify the output
  • write some test programs to test your bindings
  • publish your bindings on lazarus-ccr or Free Pascal

Install tools

The h2pas tool comes with every normal fpc installation.

Install the h2paswizard package in the Lazarus IDE. Go to "Components -> Configure installed packages ...", select from the right list the H2PasWizard package and click 'Install selection', then 'Save and rebuild IDE'. Restart the IDE and you get a new menu entry: Tools -> h2pas

Fetch C header files

The C header files .h describes the interface of a C library. They are normally not provided with the library. You have to get the sources or the development package of the library. For example the C header files of the gtk libraries are in the package gtk+-devel.

Example: MPICH2

Download the mpich2-1.0.3.tar.gz from http://www-unix.mcs.anl.gov/mpi/mpich2/ and unpack them. The .h files are under mpich2-1.0.3/src/include.

Create a working directory and name your bindings

Create a directory with a useful name. A name should not contain special characters, like spaces, umlaute, points or commas. Copy the .h files.

Example: MPICH2

The h2p directory will be used for the pascal files. The h2p/c_sources directory will be used for the .h files.

 mkdir -p h2p/c_sources
 cp mpich2-1.0.3/src/include/*.h h2p/c_sources

Create a new h2pas project with the h2pas wizard

Open the h2pas wizard: "Tools -> h2pas". This will open a window. You can switch between this window and the other IDE windows. Your last h2pas project will be loaded automatically. To create a new project click on "Settings -> New/Clear settings". Then click on the bottom button "Save settings" and choose a filename.

Example: MPICH2

Click on "Settings -> New/Clear settings". Then click on the bottom button "Save settings" and save it as h2p/mpi2.h2p.

Add the .h files to the project

In the "C header files" page you can add/delete the .h files. You can enable/disable .h files to convert only part of the files.

Example: MPICH2

Click on "C header files -> Add .h files ..." and select "mpi.h". It will be enabled automatically.

Setup the h2pas options

Under "h2pas Options" you can set the parameters for the h2pas program.

Example: MPICH2

  • Enable -e, -D, -p, -w and disable all others.
  • The -l library path is "mpich".
  • Output extension is ".pas"
  • Output directory is h2pas/, so leave it empty

Run the wizard

Click on the bottom button "Run h2pas". This will copy the <example>.h file to a temporary <example>.tmp.h file and run the tools listed under "Before h2pas". Then it runs h2pas to convert the <example>.tmp.h into <example>.inc or <example>.pas or whatever output extension you setup on the h2pas page.

If h2pas finds a syntax error, the IDE will open the example.tmp.h file and jumps to the error line. h2pas often only reports 'syntax error'. See below for a list of common problems and possible fixes.

Example: MPICH2

The h2pas wizard already contains all tools to convert all the specials of this header file, so it runs without errors.

h2pas reports an error

Here is a list of common C structures, not recognized by h2pas and how to fix them:

h2pas problem: extern "C"

Some header files contain the C++ namespace block:

 #if defined(__cplusplus)
 extern "C" {
 #endif
 ...
 #if defined(__cplusplus)
 }
 #endif

Fix: Add the Remove C++ 'extern "C"' lines to the before h2pas tools.

h2pas problem: Empty macro

Some header files contain empty macros used for further extensions:

 #define MPI_FILE_DEFINED

Fix: Add the Remove empty C macros to the before h2pas tools.

h2pas problem: Implicit array types

C allows implicit arrays in parameter types. For example:

 int MPI_Group_range_incl(MPI_Group, int, int [][3], MPI_Group *);

The int [][3] is an implicit type, which is not allowed under Pascal. h2pas supports adding pointer types. So, it enough to replace all [] with *.

Fix: Add the Replace [] with * to the before h2pas tools.

h2pas problem: Makros for 0 pointers

Some header files contain typed 0 pointers:

 #define MPI_BOTTOM      (void *)0

Fix: Add the Replace macro values 0 pointer like (char *)0 with NULL to the before h2pas tools.

Test compilation and add tools to beautify the output

When h2pas runs without errors it has created a pascal file. The -i switch defines if it is a unit or an include file. The next step is test compilation. Setup up a test project that uses the new pascal source. Then use the 'Run h2pas and compile' button in the h2pas wizard.

=Example: MPICH2

Create a new project with Project -> New Project -> Program. Save it a mpihelloworld. Change the code to

program MPIHelloWorld;

{$mode objfpc}{$H+}
{$linklib mpich}
{$linklib rt}

uses
  {$IFDEF UNIX}pthreads{$ENDIF}, MPI;

begin
  MPI_Init(@argc, @argv);
  writeln('Hello, world.');
  MPI_Finalize;
end.

Add the h2p/mpi.pas to the project. Project -> Add editor file to project.


Unit name contains the file path

h2pas sometimes add the whole path to the unitname.

Fix: Add Replace "unit filename;" with "unit name;" to the After h2pas tools.

Removing system types

h2pas adds some system types, like PLongint, which are nowadays part of the system unit.

Fix: Add Remove type redefinitons like PLongint to the After h2pas tools.

Write some test programs to test your bindings

ToDo

Publish your bindings on lazarus-ccr or Free Pascal

ToDo