From: Hoehle, Joerg-C. <Joe...@t-...> - 2006-09-22 12:50:15
|
Hi, >Sam Steingold wrote: >> I am trying to write an FFI module interface to libsvm >> http://www.csie.ntu.edu.tw/~cjlin/libsvm/ Often enough, I like to view at the original API documentation than at snippets of bogus code. I found http://public.procoders.net/cgi-bin/trac.cgi/browser/pcsvm/ but can't find the functions & structures that you want to interface to. > (def-c-type node (c-struct list (index int) (value double-float))) > (def-c-type problem (c-struct list > (l int) ; number of records > (y (c-array-ptr double-float)) ; of length l (targets) > (x (c-array-ptr (c-array-ptr node))))); of length l (predictors) I think I'm beginning to grasp your problem. The FFI is designed to do *once* a conversion between a foreign structure and a Lisp structure. What you're trying to do is a piecemeal conversion, one for each shallow allocation. You want to mimic C :-( That's why you run into the problem with the NULL slot pointer from your allocate-shallow. What you can do is play nice with the FFI, and build a Lisp structure that can be converted at once, using deep allocation. Play with Lisp as long as possible! You can also work piecemealwise. For that you'll need CAST to C-POINTER. Then you can SETF the CAST'ed slot to the FOREIGN-VARIABLE pointer. (SETF (CAST (SLOT problem 'y|x) 'c-pointer) #.#<FOREIGN-VARIABLE>) You can't SETF a slot to a C-ARRAY-PTR or some such to some foreign entity. Only Lisp objects (arrays) are acceptable arguments. >(defun alist-to-nodes (alist) > (loop :for i :upfrom 0 :for (index . value) :in alist :do > (setf (slot (element v i) 'index) index > (slot (element v i) 'value) value)) This still looks cumbersome. Why don't you create a Lisp vector of nodes and let the FFI convert that in one go? (allocate-deep 'problem '(1 #(2.0d0) #( (1 2.0d0) (2 5.6d0)))) Now write beautiful Lisp code to create that set of arrays. In case you dislike the duplication of knowledge about ordering of the slots of the node struct that you need to reproduce with '(1 2.0d0), you can use (def-c-struct node #) instead, use the struct constructor that handles ordering for you: (make-node :index ... :value ...) and supply and array of those objects. Regards, Jorg Hohle. |