2009-11-08 5 views
0

utilisant le PLT-Scheme-FFI, je veux appeler la fonction CAppel mysql_real_escape_string en utilisant l'étranger PLT-Schéma Fonction Interface

unsigned long mysql_real_escape_string(MYSQL *con, char *to, const char *from, unsigned long length) 

d'une procédure de système et continuer à utiliser la chaîne résultante « à » intérieur l'appelant. L'appel de la procédure de régime serait se présenter comme suit:

(define-values (to) (escape-string con ??? from (+ (string-length from) 1))) 

où con est une connexion valide à un MySQL-DB et échapper-chaîne est définie par

(define escape-string (get-ffi-obj "mysql_real_escape_string" libmysql 
            (_fun (con to from length) :: 
             (con : _pointer) 
             (to : (_ptr io _byte)) 
             (from : _string) 
             (length : _ulong) 
             -> (res : _ulong) 
             -> (values out)))) 

Le problème est, je ne idée de quoi passer pour '???' lors de l'appel de la chaîne d'échappement, je ne sais pas si la définition de la chaîne d'échappement est correcte.

Toute aide serait appréciée.

Cordialement,

Ralf S.

Répondre

1

En général, _ptr arguments sont utilisés lorsque le code étranger (C) attend un pointeur, mais vous voulez éviter de traiter avec un pointeur sur le côté schéma. Par exemple, (_ptr o _int) est utilisé lorsque vous avez une fonction étrangère qui attend un pointeur entier et lui attribue une certaine valeur (souvent appelée "un pointeur de sortie" d'où le "o"). Le _fun arrange pour une allocation d'un pointeur, et le déréférera quand l'appel est fait - mais la chose qui peut être déroutante est que vous devez attraper cette valeur avec un nom ou il sera simplement abandonné. Voici un exemple pour ce faire:

(_fun [r : (_ptr o _int)] -> _void -> r) 

Vous devriez lire ceci comme: passer un pointeur vers un entier à la fonction étrangère, et rendre la valeur résultante disponible r. La fonction étrangère renvoie void, mais elle est ignorée et renvoie à la place la valeur r, ce qui supprime efficacement le pointeur. Notez que puisqu'il s'agit d'un pointeur de sortie, vous n'avez pas besoin de spécifier une valeur d'entrée. Par exemple, si ce type est utilisé pour une liaison foo, alors foo attendrait aucun argument.

A (_ptr i _int) est différent: la fonction résultante s'attend un entier, allouer un pointeur quand appelé et passer ce pointeur à la fonction étrangère (de sorte que le code C voit encore un int*) puis défaussez ce pointeur après l'appel. Le but ici est de rendre facile l'utilisation de telles fonctions sans faire l'affectation fastidieuse vous-même. Notez que dans ce cas, ce correspond à une entrée dans la fonction Scheme résultante, mais ne correspond pas à une valeur qui peut être utilisée ultérieurement.

Enfin, (_ptr io _int) est une combinaison des deux: la fonction Scheme attend un entier, alloue un pointeur et y met l'entier donné, appelle la fonction C et lui donne ce pointeur, puis le déréférencie et vous donne le résultat. Par exemple, si vous avez cette fonction C:

void inc(int* p) { (*p)++; } 

alors ce serait une définition de schéma adéquat:

(define inc 
    (get-ffi-obj 'inc "foo.so" 
       (_fun [r : (_ptr io _int)] -> _void -> r))) 
+0

Merci pour la réponse. Je pense que je comprends l'exemple. Mais qu'en est-il de la fonction C suivante: void setstring (char * str) {strcpy (str, "foo"); } La définition de schéma suivante est-elle correcte? (définir setString (get-ffi-obj « setString "foo.so" (_fun [r: (_ptr io _byte)] -> vide -> r))) Si la définition est OK, comment J'appelle setstring de Scheme, de telle sorte que je peux continuer à travailler avec le résultat r? OMI quelque chose comme ceci (définir r (setString ???)) ou ce (LET ((r (setString ???))) ... devrait fonctionner. Cependant, je ne tout simplement pas savoir ce qu'il faut passer comme argument ??? to setstring –

+0

Il est presque impossible de lire le code dans ce commentaire, ainsi que d'écrire une réponse dans un commentaire.Pouvez-vous l'afficher comme une nouvelle question? Liste de diffusion PLT avec elle.) –

0

Désolé sur le format.Quand je cliqué sur le bouton d'envoi sur la boîte de commentaires, il avait l'air tout à fait différemment :-)

Quoi qu'il en soit, voici à nouveau:

... Mais qu'en est la fonction C suivante:

void setstring(char* str) { strcpy(str, "foo"); } 

La définition de schéma suivante est-elle correcte?

(define setstring 
    (get-ffi-obj 'setstring "foo.so" 
       (_fun [r : (_ptr io _byte)] -> void -> r))) 

Si la définition est OK, comment dois-je appeler setString du régime, de sorte que je peux continuer à travailler avec le résultat r? OMI quelque chose comme ça

(define r (setstring ???)) 
(do-something-with-r ... 

ou cette

(let ((r (setstring ???))) 
    (do-something-with-r ... 

devrait fonctionner. Cependant, je ne sais pas ce qu'il faut passer comme argument ??? à settring.

0

Je l'ai compris. Une définition de schéma adapté à la fonction C-

void setstring(char* str) { strcpy(str, "foo"); } 

qui est contenu dans la bibliothèque dynamique « lib.so » est

(define setstring 
    (get-ffi-obj 'setstring "lib.so" 
       (_fun (r : _u8vector) -> _void -> r)))) 

il peut être appelé par exemple comme celui-ci

> (setstring (make-u8vector 5)) 

qui imprime

> #"foo\0\0"