Sign in Join
Wiki copytemporary

Common problems when converting C header files/fr: what changed

Revision 1 to 2. Removed lines have a minus sign; added lines have a plus sign.

OldNewLine
11# h2pas rapporte une erreur
22
33Voilà une liste des structures C courantes qui ne sont pas reconnues par h2pas et comment les corriger: (NdT: les titres ne sont pas traduits pour correspondre au message de l'outil)
44
55## Problème h2pas : extern "C"
66
77Certains fichiers d'entête contiennent le bloc espace de nom de C++:
88
99``` c
1010#if defined(__cplusplus)
1111extern "C" {
1212#endif
1313...
1414#if defined(__cplusplus)
1515}
1616#endif
1717```
1818
1919Correction: Ajouter les lignes **Supprimer les lignes 'extern "C" ' de C++** dans les outils de la page Avant h2pas.
2020
2121## Problème h2pas : Empty macro
2222
2323Certains fichiers d'en-tête contiennent des macros vides utilisées pour d'autres extensions:
2424
2525``` c
2626#define MPI_FILE_DEFINED
2727```
2828
2929Correction: Ajouter la ligne **Remove empty C macros** dans les outils de la page **Avant h2pas**.
3030
3131## Problème h2pas : Implicit array types
3232
3333C autorise des tableaux implicites dans les types de paramètre. Par exemple:
3434
3535``` c
3636int MPI_Group_range_incl(MPI_Group, int, int [][3], MPI_Group *);
3737```
3838
3939int \[\]\[3\] est un type implicit, qui n'est pas permis dans Pascal. h2pas supporte l'ajout de types de pointer. Ainsi, il suffit de remplacer tous les \[\] avec *.
4040
4141Correction: Ajouter la ligne **Remplacer \[\] par *** dans les outils de la page **Avant h2pas**.
4242
4343## Problème h2pas : Macros for 0 pointers
4444
4545Certains fichiers d'entête contiennent de pointeurs typés 0:
4646
4747``` c
4848#define MPI_BOTTOM (void *)0
4949```
5050
5151Correction: Ajouter la ligne **Replace macro values 0 pointer like (char *)0 with NULL** dans les outils de la page **Avant h2pas**.
5252
5353## Problème h2pas : function types are silently skipped
5454
5555C permet de définir des types de fonctions, alros que Pascal ne permet que des pointeurs vers des fonctions (NdT: point à vérifier, Free Pascal supporte les types procéduraux). Par exemple:
5656
5757``` c
5858typedef int (MPI_Comm_copy_attr_function)(MPI_Comm, int, void *, void *,
5959 void *, int *);
6060```
6161
6262Le fichier d'entête n'utilise jamais cette définition directement, au lieu de cela, il utilise toujours des pointeurs de tels types **MPI_Comm_copy_attr_function***, par exemple :
6363
6464``` c
6565#define MPI_COMM_NULL_COPY_FN ((MPI_Comm_copy_attr_function*)0)
6666```
6767
6868La traduction peut fonctionner en procédant ainsi: faire du type de fonction un pointeur. Ce qui signifie d'ajouter un * devant la définition et de faire précéder par un P le nom et de retirer le * après chaque référence. Par exemple:
6969
7070``` c
7171typedef int (*PMPI_Comm_copy_attr_function)(MPI_Comm, int, void *, void *,
7272 void *, int *);
7373#define MPI_COMM_NULL_COPY_FN ((PMPI_Comm_copy_attr_function)0)
7474```
7575
7676Solution: Ajouter l'outil **Convertir les types de fonction en pointeurs** dans les outils de la page Avant h2pas.
7777
7878# Compilation de test et ajouter des outils pour embellir la sortie
7979
8080Lorsque h2pas s'exécute sans erreur, il a créé un fichier Pascal. Le commutateur -i définit s'il s'agit d'une unité ou d'un fichier d'inclusion. La prochaine étape est le test de compilation. Préparez un projet de test qui utilise le nouveau source Pascal. Ensuite utilisez le bouton **Exécuter H2Pas et compiler** dans l'assistant h2pas.
8181
8282### Exemple: MPICH2
8383
8484Créer un nouveau projet avec Projet -\> Nouveau Projet -\> Programme. Enregistrez-le dans **mpihelloworld**. Modifiez le code:
8585
8686``` pascal
8787program MPIHelloWorld;
8888
8989{$mode objfpc}{$H+}
9090{$linklib mpich}
9191{$linklib rt}
9292
9393uses
9494 {$IFDEF UNIX}pthreads{$ENDIF}, MPI;
9595
9696begin
9797 MPI_Init(@argc, @argv);
9898 writeln('Hello, world.');
9999 MPI_Finalize;
100100end.
101101```
102102
103103Ajoutez le h2p/mpi.pas au projet. Projet -\> Ajouter le fichier de l'éditeur au projet
104104
105105# Erreurs courantes du compilateur dans la sortie h2pas
106106
107107Parfois, h2pas ne produit pas du code Pascal valide. Voici les problèmes courants et comment les résoudre.
108108
109109## Unit name contains the file path
110110
111111Parfois h2pas ajoute le chemin complet au nom d'unité.
112112
113113Résolution: Ajouter **Remplacement de "unit filename;" par "unit name;"** dans les outils de la page Avant h2pas.
114114
115115## Missing include files
116116
117117h2pas convertit les directives \#include en directives pascal {\$i }. Si vous créez une unité pour chaque fichier d'entête C alors vopus pouvez retirer toutes les directives avec l'outil **Suppression des directives incluses**.
118118
119119## Forward type not resolved
120120
121121Par exemple **mpi.pas(26,16) Error: Forward type not resolved "PMPI_Aint"** La ligne d'erreur est souvent sur un type pointeur vers un enregistrement:
122122
123123``` pascal
124124PMPI_Aint = ^MPI_Aint;
125125```
126126
127127h2pas ajoute PMPI_Aint pour donner un nom au pointeurs C anonymes comme *MPI_Aint. Il ajoute les pointeurs au début du fichier. Mais Pascal exige que la définition soit une section de même **type**.
128128
129129Parfois h2pas ajoute un type pointer alors qu'il existe déjà.
130130
131131Résolution: Ajouter **Supprimer les types de pointeurs redéfinis** dans les outils **Après h2pas**.
132132
133133## Removing system types
134134
135135h2pas ajoute quelques types système, comme PLongint, qui font désormais partie de l'unité System.
136136
137137Résolution: Ajouter l'outil **Supprimer les redéfinitions de type comme "PLongint"** aux outils **Après h2pas**.
138138
139139## Empty type/var/const sections
140140
141141Après que les outills du dessus aient enlevé quelques variables, types, constantes, des sections deviennent vides, ce qui n'est pas permis en Pascal.
142142
143143Correction: Ajouter **Remove empty type/var/const sections** ou l'outil **Post H2Pas** aux outils **After h2pas**.
144144
145145## h2pas forgets to add IFDEFs for function bodies
146146
147147h2pas convertit les macros en functions. Mais la macro était dans un block IFDEF, h2pas n'ajoute pas les IFDEFs autour de la fonction.
148148
149149Correction: Ajouter l'outil **Add missing h2pas IFDEFs for function bodies** ou le **Post H2Pas**. Ajoutez ceci juste devant l'outil **Reduce compiler directives in pascal file**.
150150
151151## Implicit Types
152152
153153C permet les paramètres de types implicites, par exemple, *int \[\]\[3\]*. Pascal ne le permet pas, donc vous devez lui donner un nom et déclarer un type. Mais h2pas ne le fait pas automatiquement et ajoute le type implicite à la place dans une syntaxe quasi-Pascal. Par exemple:
154154
155155``` c
156156int some_func(int [][3]);
157157```
158158
159159devient
160160
161161``` pascal
162162function some_func(_para1:array[0..2] of Plongint):longint;cdecl;external;
163163```
164164
165165Correction: Heureusement, il y a maintenant un outil pour supprimer les types implicites, c'est appelé **Replace implicit types**. Cela fait aussi partie de l'outil **Post H2Pas**. Ajoutez-le dans la liste des outiles *after*.
166166
167167## Array of nothing
168168
169169Parfois h2pas convertit le type paramètre à ellipse du C '...' incorrectement en 'array of )', il devrait être convertit en 'array of const)'. Sometimes h2pas converts the C ellipsis parameter type '...' wrongly to 'array of )'. It should be 'array of const)'.
170170
171171## Identifier not found
172172
173173Il y a quatre cas:
174174
175175- The identifier is defined in the unit, but after it is used L'identificateur est défini mais après été utilisé.
176176- The identifier is defined in another unit (another .h file) L'identificateur est défini dnas une autre unité.
177177- The identifier is a pointer to an existing type, but h2pas forgot to add it L'identificateur est un pointeur sur un type existant mais h2pas a oublié de l'ajouter.
178178- The identifier is not defined anywhere L'identificateur n'est défini nulle part.
179179
180180### The identifier is defined in the unit, but after it is used
181181
182182En Pascal les types déclarés en avance sont uniquement permis dans une même section type. Par exemple:
183183
184184``` pascal
185185type
186186 TMyRecord = record
187187 Next: PMyRecord; // utilisation de la déclaration avancée
188188 end;
189189 PMyRecord = ^TMyRecord;
190190```
191191
192192Ce qui suit n'est pas permis, parce que la déclaration avancée est dans une autre section type
193193
194194``` pascal
195195type
196196 TMyRecord = record
197197 Next: PMyRecord; // utilisation de la déclaration avancée
198198 end;
199199type
200200 PMyRecord = ^TMyRecord;
201201```
202202
203203Solution: Le code doit être réordonné. Ajouter l'outil ''Corriger les déclarations avancées.
204204
205205### The identifier is defined in another unit (another .h file)
206206
207207#### Solution 1: Ajouter l'unité dans la section uses
208208
209209Si l'autre unité utilis déjà cette unité, alors vous avez un cycle. Les dépendances circulaires sont permises entre fichier .h, mais pas dans les unité Pascal. Dans ce cas, vous devez déplacer le codes entre les deux unités ou utiliser des IFDEFs comme dans les liaisons gtk2 ou utiliser la fonction de fusion de l'assistant h2pas.
210210
211211#### Solution 2: Fusionner les deux fichiers d'inclusion
212212
213213L'assistant h2pas peut fusionner des fichiers d'inclusion en un seul. Par exemple, first.h inclut via la directive d'inclusion C le fichier second.h. Sélectionner le second.h dans l'assistant et contrôler la fonctionnalité 'Merge file'. Par la suite, le source de second.h sera ajouté à first.h avant d'envoyer le sortie vers h2pas. Comme toujours, cela ne change pas les fichiers d'entêtes.
214214
215215#### Exemple: MPICH2
216216
217217Le type MPI_Request est défini dans mpi.h et utilisé dans mpio.h. Les deux fichiers d'en-tête c s'utilisent fortement l'un l'autre, vous ne pouvez donc pas les mettre dans deux unités séparées. Sélectionnez mpio.h et activez la fonction 'Merge file'.
218218
219219### The identifier is a pointer to an existing type, but h2pas forgot to add it
220220
221221Solution: Add the tool **Add missing pointer types like PPPChar** or the **Post H2Pas** tool to the **after H2Pas** tools.
222222
223223### The identifier is not defined anywhere
224224
225225Probably you are missing a header file or you are using one with the wrong version or it is private identifier.
226226
227227Solution: Search the header file and convert it too. If you can not find it or you don't want to translate this file, you can comment the identifier or replace it.
228228
229229### Exemple: MPICH2
230230
231231Note: this is just a demonstration. The real solution for the MPICH2 headers is to setup the Defines correct, so that the below example vanishes automatically.
232232
233233The mpi.h file defines MPI_File as pointer of ADIOI_FileD, but ADIOI_FileD is not defined public:
234234
235235``` c
236236typedef struct ADIOI_FileD *MPI_File;
237237```
238238
239239The h2pas tool translated this to:
240240
241241``` pascal
242242MPI_File = ^ADIOI_FileD;
243243```
244244
245245Because ADIOI_FileD is not defined public, it is a private structure, so you can simply replace it with a *Pointer*: Add to the 'After h2pas' tools a new tool of type 'Search and replace' with the following properties:
246246
247247| Propriété | Valeur |
248248|-------------|----------------------------------|
249249| Caption | Replace ADIOI_FileD with Pointer |
250250| Name | ReplaceADIOI_FileDwithPointer |
251251| SearchFor | ADIOI_FileD |
252252| ReplaceWith | Pointer |
253253| Options | \[trtMatchCase,trtWholeWord\] |
254254
255255## Illegal expression
256256
257257### Exemple: MPICH2
258258
259259Compiler gives *Illegal expression* on the following statement
260260
261261``` pascal
262262const
263263 MPI_LONG_LONG = MPI_LONG_LONG_INT;
264264```
265265
266266The reason is, that h2pas translated the MPI_LONG_LONG_INT constant to a function.
267267
268268Solution: Fix h2pas or use a trick:
269269
270270Replace the
271271
272272``` c
273273#define MPI_LONG_LONG MPI_LONG_LONG_INT
274274```
275275
276276with
277277
278278``` c
279279#define MPI_LONG_LONG ((MPI_Datatype)0x4c000809)
280280```
281281
282282by adding a **Search and replace** tool before h2pas.
283283
284284# Autres problèmes courants
285285
286286## The pascal file contains a lot of unneccessary ifdef
287287
288288h2pas translates even the C \#ifdef directives. Many of them are C specific and not needed under FPC and can even make it impossible many tools on this side to explore the code. That's why there is a tool to clean up and disable or remove many unneeded IFDEFs: **Reduce compiler directives in pascal file**. Do not forget to insert the tool **Add missing h2pas IFDEFs for function bodies** in front of it.
289289
290290### Hints about unneeded directives (\$IFDEFs, \$DEFINEs, ...)
291291
292292You can see the directives in the [[IDE Window: Code Explorer|Code Explorer]].
293293
294294The tool will only remove the \$IFDEFs and \$DEFINEs, that are unneeded on all platforms. That means for example a {\$IFDEF CPU386} will not be removed - even if you are currently working on an intel 32 bit compatible machine it will not be removed. This allows to create platform independent bindings. Of course C headers often contain a lot of IFDEFs not needed under FPC (Delphi, Kylix, gpc, ...).
295295
296296For example: Many C headers are enclosed in
297297
298298``` pascal
299299{$IFNDEF FOO}
300300{$DEFINE FOO}
301301...
302302{$ENDIF}
303303```
304304
305305This trick allows to include a C header file multiple times - like the units under pascal. So, pascal does not need this. Therefore the tool *Reduce compiler directives in pascal file* and the **Post H2Pas** tool have two properties: *Defines* and *Undefines*. Click on the *...* button of the property to edit them. Each line can contain a macroname, that should be (un)defined. Add the line *FOO* to the *Undefines*. This way the **\$IFNDEF FOO** is always true and the tool will remove it. The **\$DEFINE FOO** is now unneeded too and will be removed too.
306306
307307#### Exemple: MPICH2
308308
309309Add the following to the *Undefines* property:
310310
311-` MPI_INCLUDED`\
312-` MPIO_INCLUDE`\
313-` NEEDS_MPI_FINT`\
314-` MPI_BUILD_PROFILING`\
315-` MPICH_SUPPRESS_PROTOTYPES`\
316-` MPI_Wtime`\
317-` HAVE_MPICH2G2`\
318-` FOO`\
319-` HAVE_PRAGMA_HP_SEC_DEF`
311+```text
312+ MPI_INCLUDED
313+ MPIO_INCLUDE
314+ NEEDS_MPI_FINT
315+ MPI_BUILD_PROFILING
316+ MPICH_SUPPRESS_PROTOTYPES
317+ MPI_Wtime
318+ HAVE_MPICH2G2
319+ FOO
320+ HAVE_PRAGMA_HP_SEC_DEF
321+```
320322
321323Add the following to the *Defines* property:
322324
323-` MPICH2`\
324-` MPICH_NEW_MPIIO`
325+```text
326+ MPICH2
327+ MPICH_NEW_MPIIO
328+```
325329
326330## The C header files contain redefinitions
327331
328332This is ok for C compilers, because a type is the same if its definition is the same. But for Pascal each type is a different type.
329333
330334Solution: Add the tool **Remove redefinitions in pascal unit** or the **Post H2Pas** to the after h2pas tools. As the name implies, it only works on units, not on include files. And it expect at least a valid pascal syntax. That's why it is important to add this tool **after** the tools that fix the pascal syntax like *Replace "unit filename;" with "unit name;"*, *Remove empty type/var/const sections*, *Remove includes*, *Replace implicit types* and *Fix open arrays*.
331335
332336### Exemple: MPICH2
333337
334338The mpi.h contains several redefinitions like MPIIMPL_HAVE_MPI_TYPE_CREATE_DARRAY. They can all be fixed with this tool.
335339
336340## Alias macros are always translated by h2pas to constants
337341
338342h2pas converts macros like
339343
340344``` c
341345#define A B
342346```
343347
344348to
345349
346350``` pascal
347351const A = B;
348352```
349353
350354which is almost always correct. But some c header contain aliases for types, variables and functions too.
351355
352356### Example: MPICH2
353357
354358The mpi.h contains the macro
355359
356360``` c
357361#define MPI_LONG_LONG MPI_LONG_LONG_INT
358362```
359363
360364h2pas converts this simply to
361365
362366``` pascal
363367const
364368 MPI_LONG_LONG = MPI_LONG_LONG_INT;
365369```
366370
367371but MPI_LONG_LONG_INT is a function.
368372
369373Solution: Add the tool **Fixes section type of alias definitions in pascal unit** or the **Pre H2Pas** tool to the **Before H2Pas** tools.
370374
371375Note: This tool can also fix alias to external functions. For example:
372376
373377``` pascal
374378function ExternalFunc1(_para1:longint; _para2:pointer):longint;cdecl;external name 'ExternalFunc1';
375379const
376380 ExternalFuncAlias1 = ExternalFunc1;// should be replaced with full declaration
377381```
378382
379383## h2pas creates functions for constants
380384
381385Par exemple:
382386
383387``` pascal
384388function MPI_2COMPLEX : MPI_Datatype;
385389begin
386390 MPI_2COMPLEX:=MPI_Datatype(MPI_DATATYPE_NULL);
387391end;
388392```
389393
390394All used identifiers are types and constants, so this function can be replaced with a simple constant. This is checked and done by the tool **Replace simple functions with constants** or the **Post H2Pas**.
391395
392396## h2pas creates functions for type casts
393397
394398Par exemple:
395399
396400``` pascal
397401function PMPI_Win_f2c(win : longint) : MPI_Win;
398402begin
399403 PMPI_Win_f2c:=MPI_Win(win);
400404end;
401405```
402406
403407This function can be replaced with a simple type, resulting in a type cast. This is checked and done by the tool **Replace simple functions with type casts** or the **Post H2Pas** tool.
404408
405409## Some identifiers are used before they are defined
406410
407411C allows much more forward definitions than pascal, so the definitions must be topologically sorted. For example:
408412
409413``` pascal
410414type
411415 PMPI_Datatype = ^MPI_Datatype;
412416 MPI_Datatype = longint;
413417```
414418
415419The pointer PMPI_Datatype must be moved to the same type section as MPI_Datatype.
416420
417421Solution: Add the **Fix forward definitions by reordering** or the **Pre H2Pas** tool to the **Before H2Pas** tools. The tool should be put **after** the tools fixing redefinitions and types. At the moment the tool only moves pointer types. ToDo: reorder some more definitions like constants.
418422
419423## The C header files do not contain parameter names
420424
421425For example there is an ugly function without parameter names:
422426
423427``` c
424428int MPI_Intercomm_create(MPI_Comm, int, MPI_Comm, int, int, MPI_Comm * );
425429```
426430
427431The parameter names are defined in the corresponding .c file:
428432
429433``` c
430434int MPI_Intercomm_create(MPI_Comm local_comm, int local_leader,
431435 MPI_Comm peer_comm, int remote_leader, int tag,
432436 MPI_Comm *newintercomm)
433437```
434438
435439Solution: There is no solution yet. Except manual editing or searching for other .h files. Often such .h files were auto generated and there are some nicer header files somewhere on the internet.
436440
437441Proposal: Write a clever tool, that searches functions with missing parameter names and the corresponding functions in the .c files with parameter names and improve the .h file.
438442
439443## Voir aussi
440444
441445- [[Creating bindings for C libraries/fr|Création de liaisons pour des bibliothèques C]]
442446- [[Pascal for C users/fr|Pascal pour les utilisateurs du C]]
443447- [[Pascal for C++ users/fr|Pascal pour les utilisateurs du C++]]
444448- [[SWIG/fr|SWIG]]
445449
446450---
447451*From the Free Pascal wiki, page "Common problems when converting C header files/fr", as it stood on 2023-03-21 after a change by E-ric, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*

Back to history