2009-11-17 9 views
3

J'essayais d'écrire mon propre put-pixel sur (Gdk) pixbuf en Lisp. Quand j'ai finalement réalisé comment je peux opérer sur des pointeurs C en CL, un nouvel obstacle est apparu - (gdk: pixbuf-get-pixels pb) me renvoie un nombre négatif. Ma question est la suivante: puis-je le convertir en quelque sorte à un pointeur valide? Mes tentatives d'utiliser cffi: convert-from-foreign et cffi: translate-from-foreign (quelle est la différence entre elles?) Échouent.lambda-gtk pointeur négatif

Ci-dessous mon code actuel (ne fonctionne pas):

(defun put-pixel (pixbuf x y r g b) 
    (let ((p (+ (gdk:pixbuf-get-pixels pixbuf) (* x (gdk:pixbuf-get-n-channels pixbuf)) (* y (gdk:pixbuf-get-rowstride pixbuf))))) 
    (setf (cffi:mem-aref p :unsigned-char 0) r) 
    (setf (cffi:mem-aref p :unsigned-char 1) g) 
    (setf (cffi:mem-aref p :unsigned-char 2) b))) 

Répondre

2

Je pense que lambda-gtk a défini de façon incorrecte la liaison pour pixbuf-get-pixels.

La valeur négative de la valeur du pointeur peut apparaître en raison d'une interprétation incorrecte de l'entier non signé en tant qu'entier entier.

La façon la plus simple de corriger cette valeur est d'utiliser mod:

CL-USER> (mod -1 (expt 2 #+cffi-features:x86 32 #+cffi-features:x86-64 64)) 
4294967295 
+0

Eh bien, il semble que quelque chose est vraiment mal avec cette fonction. J'ai dû essayer une approche différente. – x13n

5

CFFI:TRANSLATE-FROM-FOREIGN est une fonction générique. Vous pouvez définir vos propres types étrangers en utilisant CFFI:DEFINE-FOREIGN-TYPE, puis ajouter une méthode à CFFI: TRANSLATE-FROM-FOREIGN pour spécifier comment les conversions de valeurs étrangères à Lisp devraient fonctionner.

CFFI:CONVERT-FROM-FOREIGN est ce que vous devriez appeler si vous avez besoin de convertir explicitement une valeur. Il appellera CFFI: TRANSLATE-FROM-FOREIGN dans les coulisses et il pourrait effectuer des optimisations à la compilation si possible. La même chose s'applique aux codes CFFI:CONVERT-TO-FOREIGN et CFFI:TRANSLATE-TO-FOREIGN.