Twitter iPhone pliant OnePlus 11 PS5 Disney+ Orange Livebox Windows 11

swig

9 réponses
Avatar
Wilk
slt,

J'essaye de créer un wrapper pour une bibliothèque C, et je bute sur un
problème :

Le header commence par :

typedef struct _Dictionary* Dictionary;
typedef unsigned int uint_t;

/*************************
*
*************************/

int Dic_load (Dictionary*,const char*);
int Dic_destroy(Dictionary);

/*************************
* functions to access the elements
*************************/

char Dic_chr (Dictionary,uint_t);
int Dic_last(Dictionary,uint_t);

Je cré un fichier dico.i :

%module dico
%{
#include "dic.h"
%}
%include "dic.h"

Les fonctions Dic_load, Dic_destroy etc. Sont bien exportées, mais je
n'arrive pas à exporter Dictionary, hors il faut que je cré une instance
de Dictionary pour la passer à Dic_load...

merci des tuyaux...

--
Wilk - http://flibuste.net

9 réponses

Avatar
Alexandre Fayolle
Le 30-07-2004, Wilk a écrit :

Les fonctions Dic_load, Dic_destroy etc. Sont bien exportées, mais je
n'arrive pas à exporter Dictionary, hors il faut que je cré une instance
de Dictionary pour la passer à Dic_load...



Swig wrap les structures avec des pointeurs opaque. Si tu veux passer
des dictionnaires python à tes fonctions C, faut expliquer à Swig
comment faire la conversion, en lui fournissant un typemap.

http://www.swig.org/Doc1.3/Typemaps.html

Avatar
Wilk
Alexandre Fayolle writes:

Le 30-07-2004, Wilk a écrit :

Les fonctions Dic_load, Dic_destroy etc. Sont bien exportées, mais je
n'arrive pas à exporter Dictionary, hors il faut que je cré une instance
de Dictionary pour la passer à Dic_load...



Swig wrap les structures avec des pointeurs opaque. Si tu veux passer
des dictionnaires python à tes fonctions C, faut expliquer à Swig
comment faire la conversion, en lui fournissant un typemap.


Non, c'est l'inverse, dans ce cas, Dictionary est un pointeur de struct
C, rien à voir avec un dictionaire python en fait et je n'arrive pas à
le récupérer pour l'envoyer dans les fonctions.

En C je fait :

#include dic.h
...
Dictionary dic = NULL;
Dic_load(&dic, "ods4.dawg");
if (Dic_search_word(dic, "test"))
...

Hors avec swig je n'arrive pas à obtenir Dictionary pour le créer et le
passer en argument à Dic_load etc.

Pour info, la librairie en question permet de trouver les coups de
scrabble, si ça peut intéresser quelqu'un d'autre.
http://afrab.free.fr/eliot/

--
Wilk - http://flibuste.net


Avatar
Alexandre Fayolle
Le 30-07-2004, Wilk a écrit :
Alexandre Fayolle writes:

Le 30-07-2004, Wilk a écrit :

Les fonctions Dic_load, Dic_destroy etc. Sont bien exportées, mais je
n'arrive pas à exporter Dictionary, hors il faut que je cré une instance
de Dictionary pour la passer à Dic_load...



Swig wrap les structures avec des pointeurs opaque. Si tu veux passer
des dictionnaires python à tes fonctions C, faut expliquer à Swig
comment faire la conversion, en lui fournissant un typemap.


Non, c'est l'inverse, dans ce cas, Dictionary est un pointeur de struct
C, rien à voir avec un dictionaire python en fait et je n'arrive pas à
le récupérer pour l'envoyer dans les fonctions.

En C je fait :

#include dic.h
...
Dictionary dic = NULL;
Dic_load(&dic, "ods4.dawg");
if (Dic_search_word(dic, "test"))
...

Hors avec swig je n'arrive pas à obtenir Dictionary pour le créer et le
passer en argument à Dic_load etc.


Ca ne change rien à ce que j'ai dit ci dessus. Il faut que tu ajoutes à
ton wrapper swig une fonction Dictionary* allocate_Dict(void) qui alloue
un dictionnaire sur le tas, et une fonction free_Dict(Dictionary*) qui
libère le dictionnaire.



Avatar
Wilk
Alexandre Fayolle writes:

Le 30-07-2004, Wilk a écrit :
Alexandre Fayolle writes:

Le 30-07-2004, Wilk a écrit :

Les fonctions Dic_load, Dic_destroy etc. Sont bien exportées, mais je
n'arrive pas à exporter Dictionary, hors il faut que je cré une instance
de Dictionary pour la passer à Dic_load...



Swig wrap les structures avec des pointeurs opaque. Si tu veux passer
des dictionnaires python à tes fonctions C, faut expliquer à Swig
comment faire la conversion, en lui fournissant un typemap.


Non, c'est l'inverse, dans ce cas, Dictionary est un pointeur de struct
C, rien à voir avec un dictionaire python en fait et je n'arrive pas à
le récupérer pour l'envoyer dans les fonctions.

En C je fait :

#include dic.h
...
Dictionary dic = NULL;
Dic_load(&dic, "ods4.dawg");
if (Dic_search_word(dic, "test"))
...

Hors avec swig je n'arrive pas à obtenir Dictionary pour le créer et le
passer en argument à Dic_load etc.


Ca ne change rien à ce que j'ai dit ci dessus. Il faut que tu ajoutes à
ton wrapper swig une fonction Dictionary* allocate_Dict(void) qui alloue
un dictionnaire sur le tas, et une fonction free_Dict(Dictionary*) qui
libère le dictionnaire.



C'est ce que j'ai fait finalement, mais je pensais que c'était du
bidouillage...

Est-ce que les noms "allocate_" et "free_" doivent impérativement être
nommés comme ça ? Et est-ce qu'il faut que je les écrive dans le
source C (ce que j'ai fait) ou dans l'interface swig ?

--
Wilk - http://flibuste.net




Avatar
Alexandre Fayolle
Le 04-08-2004, Wilk a écrit :

C'est ce que j'ai fait finalement, mais je pensais que c'était du
bidouillage...


C'est du bidouillage, mais c'est pas comme si tu avais le choix ;-)

Avec swig, dès qu'on a a manipuler autre chose que les types primitifs,
on bidouille beaucoup. Assez rapidement on se rend compte qu'écrire le
wrapper à la main, c'est pas si difficile que ça...


Est-ce que les noms "allocate_" et "free_" doivent impérativement être
nommés comme ça ?


Non. Tu peux les appeler trululu et tagada, si tu préfères. Après c'est
une question de lisibilité.

Et est-ce qu'il faut que je les écrive dans le
source C (ce que j'ai fait) ou dans l'interface swig ?


En général, je préfère ne pas toucher au source C quand j'enrobe une
bibliothèque, et j'utilise les %{ ... %} que m'offre swig pour ajouter
du code au wrapper. Mais c'est parce que, assez souvent, je me retrouve
avec du code C dont je ne suis pas l'auteur, et ça me permet de
simplifier le travail lorsqu'une nouvelle version est mise à
disposition.

Ne pas oublier de wrapper ces deux fonctions, pour pouvoir les appeler
depuis python.

--
Alexandre Fayolle LOGILAB, Paris (France).
http://www.logilab.com http://www.logilab.fr http://www.logilab.org

Avatar
Wilk
Alexandre Fayolle writes:

Le 04-08-2004, Wilk a écrit :

C'est ce que j'ai fait finalement, mais je pensais que c'était du
bidouillage...


C'est du bidouillage, mais c'est pas comme si tu avais le choix ;-)


ok, merci, tu me rassure.


Avec swig, dès qu'on a a manipuler autre chose que les types primitifs,
on bidouille beaucoup. Assez rapidement on se rend compte qu'écrire le
wrapper à la main, c'est pas si difficile que ça...


C'est ce que j'ai commencé à faire ! Mais je trouve que c'est
assez fastidieux quand même...



Est-ce que les noms "allocate_" et "free_" doivent impérativement être
nommés comme ça ?


Non. Tu peux les appeler trululu et tagada, si tu préfères. Après c'est
une question de lisibilité.

Et est-ce qu'il faut que je les écrive dans le
source C (ce que j'ai fait) ou dans l'interface swig ?


En général, je préfère ne pas toucher au source C quand j'enrobe une
bibliothèque, et j'utilise les %{ ... %} que m'offre swig pour ajouter
du code au wrapper. Mais c'est parce que, assez souvent, je me retrouve
avec du code C dont je ne suis pas l'auteur, et ça me permet de
simplifier le travail lorsqu'une nouvelle version est mise à
disposition.


Ce que j'ai fait c'est de créer un source C externe, à moi. Ça revient
donc au même...

Est-ce qu'il ne serait pas plus simple/propre d'utiliser pyrex ?


Ne pas oublier de wrapper ces deux fonctions, pour pouvoir les appeler
depuis python.


--
Wilk - http://flibuste.net


Avatar
Wilk
slt,

Maintenant que mon wrapper marche ! youpi ! est-ce qu'il y a un moyen de
rattraper une erreur brutale du programme C ?

--
Wilk - http://flibuste.net
Avatar
Xavier Combelle
Wilk wrote:
slt,

Maintenant que mon wrapper marche ! youpi ! est-ce qu'il y a un moyen de
rattraper une erreur brutale du programme C ?



Si ce que tu appelles une erreur brutale en C, c'est un core Dump ou un
Segmentation fault, il n'y a pas de solution.
Je crois que ca vaut mieux, car, une fois que ca s'est produit,
le programme c, n'est plus du tout fiable.
Par contre, si tu veux que l'ensemble de ton application résiste aux
coredump, je te propose que la partie qui contient du c soit un serveur
pour ton application principale. Comme ca, si ton serveur crashe, ton
application principale peut gérer ca de facon élégante.

Por le protocole utilisé pour communiquer entre le client et le serveur
est bien sûr le protocole HTTP, comme je l'ai déjà expliqué dans la
discussion précédente intitulée "Wanted ping"?.

Avatar
Wilk
Xavier Combelle writes:

Wilk wrote:
slt,
Maintenant que mon wrapper marche ! youpi ! est-ce qu'il y a un
moyen de
rattraper une erreur brutale du programme C ?



Si ce que tu appelles une erreur brutale en C, c'est un core Dump ou
un Segmentation fault, il n'y a pas de solution.
Je crois que ca vaut mieux, car, une fois que ca s'est produit,
le programme c, n'est plus du tout fiable.


C'est bien ce que je pensais...

Par contre, si tu veux que l'ensemble de ton application résiste aux
coredump, je te propose que la partie qui contient du c soit un
serveur pour ton application principale. Comme ca, si ton serveur
crashe, ton application principale peut gérer ca de facon élégante.


Oui, bonne idée, surtout qu'il s'agit déjà d'une application serveur.


Por le protocole utilisé pour communiquer entre le client et le
serveur est bien sûr le protocole HTTP, comme je l'ai déjà expliqué
dans la discussion précédente intitulée "Wanted ping"?.



--
Wilk - http://flibuste.net