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

PERL embarqué dans du code C: parametre de type char *

10 réponses
Avatar
bertolodavid
Bonjour a tous

Je ne suis pas sur d'etre sur le bon newsgroup mais au cas ou...
J'essaye d'utiliser une fonction definie dans un script PERL a partir
d'un code C.

J'ai trouv=E9 sur le web un exemple qui fonctionne bien avec un entier
en parametre ici:
http://www.unix.org.ua/orelly/perl/prog3/ch21_04.htm
Mais je n'en ai pas trouv=E9 avec un char * en parametre.

En cherchant ici:
http://www.bribes.org/perl/docfr/perlapi.html#LC413E8CE
ou dans les .h (EXTERN.h, perl.h, XSUB.h), je trouve des infos sur les
differentes macros utilis=E9es
et sur celles qui devrait me permettre de passer un char * en
parametre mais sans succ=E9s.

Je reste bloqu=E9 sur une exemple dont je pense qu'il devrait tourner
mais qui ne compile pas et qui me donne cette erreur:
gcc -o perlinC perlinC.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
gcc: warning: `-x arch=3Dv8' after last input file has no effect
perlinC.c: In function `modif':
perlinC.c:18: error: `targ' undeclared (first use in this function)
perlinC.c:18: error: (Each undeclared identifier is reported only once
perlinC.c:18: error: for each function it appears in.)

Si quelqu'un a une piste ou a deja ete confront=E9 au meme probleme, je
suis preneur de toutes infos.

Merci d'avance

David

10 réponses

Avatar
Paul Gaborit
À (at) Tue, 25 Sep 2007 06:18:53 -0700,
écrivait (wrote):
Je ne suis pas sur d'etre sur le bon newsgroup mais au cas ou...
J'essaye d'utiliser une fonction definie dans un script PERL a partir
d'un code C.


Pour cela, il faut lire 'perlembed'.

J'ai trouvé sur le web un exemple qui fonctionne bien avec un entier
en parametre ici:
http://www.unix.org.ua/orelly/perl/prog3/ch21_04.htm
Mais je n'en ai pas trouvé avec un char * en parametre.

En cherchant ici:
http://www.bribes.org/perl/docfr/perlapi.html#LC413E8CE
ou dans les .h (EXTERN.h, perl.h, XSUB.h), je trouve des infos sur les
differentes macros utilisées
et sur celles qui devrait me permettre de passer un char * en
parametre mais sans succés.


Il faut peut-être aussi lire 'perlguts'.

Je reste bloqué sur une exemple dont je pense qu'il devrait tourner
mais qui ne compile pas et qui me donne cette erreur:
gcc -o perlinC perlinC.c `perl -MExtUtils::Embed -e ccopts -e ldopts`
gcc: warning: `-x arch=v8' after last input file has no effect


Même si cela ne chagera pas grand chose au résultat, a priori, il faut
placer l'appel à `perl ...` avant le fichier source (je sais, dans
'perlembed' ils font comme ci-dessus) :

gcc `perl -MExtUtils::Embed -e ccopts -e ldopts` -o perlinC perlinC.c

perlinC.c: In function `modif':
perlinC.c:18: error: `targ' undeclared (first use in this function)
perlinC.c:18: error: (Each undeclared identifier is reported only once
perlinC.c:18: error: for each function it appears in.)

Si quelqu'un a une piste ou a deja ete confronté au meme probleme, je
suis preneur de toutes infos.


Ma boule de cristal étant cassée, sans voir le fichier perlinC.c,
c'est très dur de comprendre d'où vient le problème. Ah si ! C'est à
la ligne 18 que ça se passe... mais vous vous en doutiez déjà !

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
bertolodavid
Voila le bout de code que j'essaye de faire compiler:

/* How to compile: */
/* gcc -o perlinC perlinC.c `perl -MExtUtils::Embed -e ccopts -e
ldopts` */

#include <EXTERN.h> /* from the Perl distribution */
#include <perl.h> /* from the Perl distribution */
#include "XSUB.h"

static PerlInterpreter *my_perl; /*** The Perl interpreter ***/

static void modif(char* input, size_t inputEDILen)
{
dSP; /* initialize stack pointer
*/
ENTER; /* everything created after here
*/
SAVETMPS; /* ...is a temporary variable.
*/
PUSHMARK(SP); /* remember the stack pointer
*/
XPUSHp(input, inputEDILen ); /* push the input string onto the
stack */
PUTBACK; /* make local stack pointer global
*/
call_pv("modif", G_SCALAR); /* call the function
*/
SPAGAIN; /* refresh stack pointer
*/
/* pop the return value from stack
*/
printf ("%s => %s n", input, POPp);
PUTBACK;
FREETMPS; /* free that return value
*/
LEAVE; /* ...and the XPUSHed "mortal" args
*/
}

int main(int argc, char **argv, char **env)
{
char inputEDI[] = "toto";

char *my_argv[] = { "", "test3.pl" };
size_t inputEDILen = strlen(inputEDI);

my_perl = perl_alloc();
perl_construct( my_perl );

perl_parse(my_perl, NULL, 2, my_argv, (char **)NULL);
perl_run(my_perl);

modif( (char *) inputEDI, inputEDILen);

perl_destruct(my_perl);
perl_free(my_perl);

}
Avatar
Paul Gaborit
À (at) Wed, 26 Sep 2007 01:22:35 -0700,
écrivait (wrote):
[...]
XPUSHp(input, inputEDILen ); /* push the input string onto the
stack */


Dans 'perlapi', la macro XPUSHp indique bien qu'elle utilise TARG.
D'où le problème. Essayez avec la version sans TARG :

/* push the input string onto the stack */
mXPUSHp(input, inputEDILen );

Cela semble marcher... mais je ne sais d'où vient votre exemple ni ce
qu'il est censé faire. J'ai donc improvisé un fichier test3.pl :

sub modif {
print "@_n";

return reverse $_[0];
}

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
bertolodavid
On 26 sep, 14:47, Paul Gaborit wrote:
À (at) Wed, 26 Sep 2007 01:22:35 -0700,
écrivait (wrote):
[...]

XPUSHp(input, inputEDILen ); /* push the input string onto the
stack */


Dans 'perlapi', la macro XPUSHp indique bien qu'elle utilise TARG.
D'où le problème. Essayez avec la version sans TARG :

/* push the input string onto the stack */
mXPUSHp(input, inputEDILen );

Cela semble marcher... mais je ne sais d'où vient votre exemple ni ce
qu'il est censé faire. J'ai donc improvisé un fichier test3.pl :

sub modif {
print "@_n";

return reverse $_[0];
}

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>


Bonjour

Merci pour la réponse et désolé pour le temps de réponse mais j'ai été
malade quelques jours.

Si j'essaye avec mXPUSHp, je me fais jeter a la compilation:
Undefined first referenced
symbol in file
mXPUSHp /tmp/dbertolo/ccWeM3Ec.o

En cherchant a la main dans les headers, je ne trouve pas la
definition de mXPUSHp nulle part.
Quelles sont les fichiers que vous incluez?

David


Avatar
Paul Gaborit
À (at) Wed, 03 Oct 2007 06:48:17 -0700,
écrivait (wrote):
Si j'essaye avec mXPUSHp, je me fais jeter a la compilation:
Undefined first referenced
symbol in file
mXPUSHp /tmp/dbertolo/ccWeM3Ec.o

En cherchant a la main dans les headers, je ne trouve pas la
definition de mXPUSHp nulle part.
Quelles sont les fichiers que vous incluez?


Je n'ai rien changé au source que vous avez fourni sauf cet appel à
mXPUSHp. Les fichiers inclus sont donc les mêmes que pour vous.

Avez-vous vérifié sa description dans 'perlapi' (sur votre
machine en utilisant 'perldoc perlapi') ?

Quelle version de Perl utilisez-vous ? Sur une version 5.8.x (x>=5),
ça marche bien. Par contre, cet appel n'existait pas en 5.6.x... Mais
je n'ai plus de quoi tester cette vieille version.

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
bertolodavid
On 3 oct, 16:59, Paul Gaborit wrote:
À (at) Wed, 03 Oct 2007 06:48:17 -0700,
écrivait (wrote):

Avez-vous vérifié sa description dans 'perlapi' (sur votre
machine en utilisant 'perldoc perlapi') ?


Je ne trouve pas mXPUSHp dans 'perlapi'


Quelle version de Perl utilisez-vous ? Sur une version 5.8.x (x>=5),
ça marche bien. Par contre, cet appel n'existait pas en 5.6.x... Mais
je n'ai plus de quoi tester cette vieille version.



J'utilise: perl, v5.8.4 built for sun4-solaris-64int

David

Avatar
Paul Gaborit
À (at) Wed, 03 Oct 2007 09:28:35 -0700,
écrivait (wrote):
Je ne trouve pas mXPUSHp dans 'perlapi'


C'est donc que c'est apparu avec la version 5.8.5...


Quelle version de Perl utilisez-vous ? Sur une version 5.8.x (x>=5),
ça marche bien. Par contre, cet appel n'existait pas en 5.6.x... Mais
je n'ai plus de quoi tester cette vieille version.



J'utilise: perl, v5.8.4 built for sun4-solaris-64int


Peut-être pouvez-vous utiliser une version plus récente...

Sinon, il va falloir se pencher sur l'utilisation de 'TARG' (une sorte
d'optimisation permettant de réutiliser plusieurs fois le même 'SV*').
Mais cela peut avoir des effets de bord. Pour en savoir plus, lire
'perlguts'. A priori, il suffit d'ajouter la ligne :

dTARG;

dans vos définitions en début de fonction. Mais mon test rapide ici,
bien que compilant correctement, mênent à une erreur (de
segmentation). J'ai la flemme de chercher pourquoi... ;-)

Il faut peut-être aussi repartir des exemples présents dans le
'perlembeded' de *votre* version qui seront certainement plus adaptés
que ceux qu'on trouve sur Internet (et qui ne correspondent sans doute
pas à votre version).

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>


Avatar
bertolodavid
On 3 oct, 18:45, Paul Gaborit wrote:
À (at) Wed, 03 Oct 2007 09:28:35 -0700,
écrivait (wrote):

Je ne trouve pas mXPUSHp dans 'perlapi'


C'est donc que c'est apparu avec la version 5.8.5...



Quelle version de Perl utilisez-vous ? Sur une version 5.8.x (x>=5),
ça marche bien. Par contre, cet appel n'existait pas en 5.6.x... Mais
je n'ai plus de quoi tester cette vieille version.


J'utilise: perl, v5.8.4 built for sun4-solaris-64int


Peut-être pouvez-vous utiliser une version plus récente...



Je peux faire un test avec une version plus recente mais je ne suis
pas sur de pouvoir l'utiliser sur la machine la cible.
Vous utilisez quelle version de PERL?

David



Avatar
Paul Gaborit
À (at) Thu, 04 Oct 2007 05:15:58 -0700,
écrivait (wrote):
Je peux faire un test avec une version plus recente mais je ne suis
pas sur de pouvoir l'utiliser sur la machine la cible.


C'est quoi comme machine cible ? A priori, si la version 5.8.4
s'installe, vous ne devriez pas avoir de problème pour installer une
version 5.8.8 (en attendant la 5.10 qui doit sortir très bientôt).

Vous utilisez quelle version de PERL?


Une petit remarque d'écriture :

- Perl : c'est le langage lui-même.
- perl : c'est une distribution de Perl
- PERL : ça n'existe pas... ;-)

Donc les versions de perl que nous utilisons ici sont :

- La version 5.6.1 installée par Solaris sur le Sun (en fait,
on ne l'utilise pas mais elle est là).
- La version 5.8.5 que nous installons dans les vieilles versions de
Solaris (sans le multi-thread).
- La version 5.8.6 installée par MacOS X sur les mac.
- La version 5.8.8 que nous installons dans Solaris, FreeBSD, Fedora,
Ubuntu, MacOS X et Windows...

--
Paul Gaborit - <http://perso.enstimac.fr/~gaborit/>
Perl en français - <http://perl.enstimac.fr/>

Avatar
bertolodavid
On 4 oct, 16:22, Paul Gaborit wrote:
À (at) Thu, 04 Oct 2007 05:15:58 -0700,
écrivait (wrote):

Je peux faire un test avec une version plus recente mais je ne suis
pas sur de pouvoir l'utiliser sur la machine la cible.


C'est quoi comme machine cible ? A priori, si la version 5.8.4
s'installe, vous ne devriez pas avoir de problème pour installer une
version 5.8.8 (en attendant la 5.10 qui doit sortir très bientôt).



Ce n'est pas un pouvoir de possibilité mais de permission :)

Vous utilisez quelle version de PERL?


Une petit remarque d'écriture :

- Perl : c'est le langage lui-même.
- perl : c'est une distribution de Perl
- PERL : ça n'existe pas... ;-)



Ok merci

Donc les versions de perl que nous utilisons ici sont :

- La version 5.6.1 installée par Solaris sur le Sun (en fait,
on ne l'utilise pas mais elle est là).
- La version 5.8.5 que nous installons dans les vieilles versions de
Solaris (sans le multi-thread).
- La version 5.8.6 installée par MacOS X sur les mac.
- La version 5.8.8 que nous installons dans Solaris, FreeBSD, Fedora,
Ubuntu, MacOS X et Windows...


Votre exemple fonctionne correctement avec cette version de perl:
perl, v5.8.8 built for i486-linux-gnu-thread-multi

Me reste plus qu'a trouver comment le faire fonctionner avec ma
version de perl.

Merci beaucoup pour votre aide.

David