langage R - passer arguments character à C (par .C)

Postez ici vos questions, réponses, commentaires ou suggestions - Les sujets seront ultérieurement répartis dans les archives par les modérateurs

Modérateur : Groupe des modérateurs

Harold Petithomme
Messages : 8
Enregistré le : 28 Jan 2008, 14:38

langage R - passer arguments character à C (par .C)

Messagepar Harold Petithomme » 28 Jan 2008, 19:17

Bonjour,

J'ai un problème avec le langage R, adapté de S et SPLUS, je crois.
J'obtiens une erreur de segmentation (segmentation fault) en passant un argument de type character à un appel à une fonction C compilée dans un shared object (.so) par .C et chargé dans R par dyn.load()

D'après la doc, les arguments character correspondent à des pointeurs de type char ** en C.

1. quelle est la forme de l'allocation du pointeur char **s faite par R? Un seul bloc de dimension n*LEN (n: nombre d'éléments de mon vecteur character et LEN, la taille supposée d'un élément) ou un pointeur dynamique (style C) où les n blocs sont non contigus?

2. dans le cas où R alloue un bloc unique n*LEN, quelle est la valeur de LEN? 255, comme la doc semble le dire pour Fortran (en Fortran, il faut utiliser un argument character*255) ou pas?

3. Comment utiliser le i-ème élément de mon vecteur (appelons-le s en C) : s[i] ou (*s)+LEN*i (avec LEN=255?) ou autre chose?

Les réponses à 2 et 3 dépendent fortement de 1., alors c'est bien la Q 1 qui est fondamentale.

Un petit exemple (suivant la taille de n ou des éléments de s (100 ici), ça plante) :
Programme R :
n = 50

cat("R call to litchar\n")
dyn.load("lit.so")
ret = .C("litchar",noms=character(n),as.integer(n))
---

Code C :
#include <stdlib.h>
#include <stdio.h>
#include <string.h>

void litchar(char **s,int *n)
{
int i, j, c;

for (i=0;i<*n;i++) {
sprintf(s[i],"%6d ",i); /* écrit 'i' dans s' i-eme element... */
c = 'a' + (i % 26); /* c est la i-eme lettre de l'alphabet */
for (j=7 ; j<100 ; j++) s[i][j] = c; /* ... ajoute à s[i] des aaaaa, des bbbbb, etc. */
s[i][j] = 0; /* terminateur C */

fprintf(stderr,"s[%6d] : \"%s\" (%p)\n",i,s[i], s[i]); /* écrit i, l'elementi de s et son adresse */
}
}

Merci à tous.
HP
HP.

François Bonnot
Messages : 537
Enregistré le : 10 Nov 2004, 15:19
Contact :

Messagepar François Bonnot » 29 Jan 2008, 06:56

Bonjour,

Des éléments de réponse se trouvent peut-être ici :

http://forums.cirad.fr/logiciel-R/viewtopic.php?p=3167

FB

Harold Petithomme
Messages : 8
Enregistré le : 28 Jan 2008, 14:38

Messagepar Harold Petithomme » 29 Jan 2008, 14:55

François Bonnot a écrit :Bonjour,

Des éléments de réponse se trouvent peut-être ici :

http://forums.cirad.fr/logiciel-R/viewtopic.php?p=3167

FB


Merci, mais non, j'ai déjà cherché un peu partout sur le net, les forums et je n'ai pas les réponses adéquates.

Merci quand même.

Si quelqu'un à une explication, je suis toujours preneur.
Merci
HP.

jean lobry
Messages : 733
Enregistré le : 17 Jan 2008, 20:00
Contact :

Messagepar jean lobry » 29 Jan 2008, 20:04

Bonjour,

je dirais que les constantes de type chaîne de caractère sont des char*, mais les variables de type character dans R étant des vecteurs, elles doivent être sous forme de char**.

Un exemple tiré de la fonction s2c() du paquet seqinr qui convertit une chaîne de caractères en un vecteur de caractères :

Code : Tout sélectionner

> s2c("toto")
[1] "t" "o" "t" "o"
> s2c
function (string)
{
    if (is.character(string) && length(string) == 1) {
        return(.Call("s2c", string, PACKAGE = "seqinr"))
    }
    else {
        warning("Wrong argument type in s2c(), NA returned")
        return(NA)
    }
}


Code : Tout sélectionner

/*##################################################*/
/*# Converts a String into a vector of characters  #*/
/*##################################################*/


SEXP s2c(SEXP seq){
  char *string;
  int lseq, i;
  char mot[2] = {'\0', '\0'};
   
  SEXP chaine;

  string = (char *) CHAR(STRING_ELT(seq, 0));
 
  lseq = strlen(string);
 
  PROTECT(chaine = NEW_CHARACTER(lseq));

  for(i = 0 ; i < lseq ; i++){ 
    mot[0] = string[i];
    SET_STRING_ELT(chaine, i, mkChar(mot));
    }

  UNPROTECT(1);
  return(chaine);
}


HTH,

Jean


Retourner vers « Questions en cours »

Qui est en ligne

Utilisateurs parcourant ce forum : Aucun utilisateur enregistré et 1 invité