Need help accessing a nested struct member?

Joeish W joeish80829 at yahoo.com
Mon Oct 7 15:25:28 UTC 2013


I do apoligize if i added to much code on this....it just seems difficult to explain without showing all the code involve. pls let me know if this isnt worded right to community guidelines and i'll edit it....pls be precise so i know what to change..

here is how the struct CvSeq is defined


#define CV_TREE_NODE_FIELDS(node_type)                               \
    int       flags;             /* Miscellaneous flags.     */      \
    int       header_size;       /* Size of sequence header. */      \
    struct    node_type* h_prev; /* Previous sequence.       */      \
    struct    node_type* h_next; /* Next sequence.           */      \
    struct    node_type* v_prev; /* 2nd previous sequence.   */      \
    struct    node_type* v_next  /* 2nd next sequence.       */

/*
   Read/Write sequence.
   Elements can be dynamically inserted to or deleted from the sequence.
*/
#define CV_SEQUENCE_FIELDS()                                              \
    CV_TREE_NODE_FIELDS(CvSeq);                                           \
    int       total;          /* Total number of elements.            */  \
    int       elem_size;      /* Size of sequence element in bytes.   */  \
    schar*    block_max;      /* Maximal bound of the last block.     */  \
    schar*    ptr;            /* Current write pointer.               */  \
    int       delta_elems;    /* Grow seq this many at a time.        */  \
    CvMemStorage* storage;    /* Where the seq is stored.             */  \
    CvSeqBlock* free_blocks;  /* Free blocks list.                    */  \
    CvSeqBlock* first;        /* Pointer to the first sequence block. */

typedef struct CvSeq
{
    CV_SEQUENCE_FIELDS()
}
CvSeq;




and here is how i ended up wrapping it.



;; (cffi:foreign-type-size '(:struct cv-seq)) = 96
(cffi:defcstruct cv-seq
    (flags :int)
    (header-size :int)
    (h-prev :pointer)
    (h-next :pointer)
    (v-prev :pointer)
    (v-next :pointer)
    (total :int)
    (elem-size :int)
    (block-max :pointer)
    (ptr :pointer)
    (delta-elems :int)
    (storage :pointer)
    (free-blocks :pointer)
    (first :pointer))



I was curious what to do with the h_next h_prev and v_prev and v_next, they seem to be recursive and they are not working or i am not using them right normally when a struct contains a  member like  CvMemStorage* storage; I wrap it like this (:pointer (:struct cv-mem-storage)) and it works but h_next i/e seems to point back to itself



this is the way the h_next struct member works in c.  in the below code while contours is not null it iterates though a while loop and through every iteration it sets the variable contours to the next pointer stored in h_next which is set by the cvFindContours function. the cvFindContours fubction in c adds a pointer to the h_next member of the CvSeq struct for every item in the picture it finds...pls see below link for more details and example picture (trying 2 keep this short)  ...  



the code i got the below snippet from is the first program on this page.....http://opencv-srf.blogspot.com/2011/09/object-detection-tracking-using-contours.html  (i broke it down so it would be easier to understand)




int main()
{

IplImage* img =  cvLoadImage("/home/w/quicklisp/dists/quicklisp/software/cl-opencv-master/images/FindingContours.png");
//converting the original image into grayscale
IplImage* imgGrayScale = cvCreateImage(cvGetSize(img), 8, 1); 
CvMemStorage *storage = cvCreateMemStorage(0); //storage area for all contours
 CvSeq* contours= cvCreateSeq(CV_SEQ_ELTYPE_POINT, sizeof(CvSeq), sizeof(CvPoint), storage);
//finding all contours in the image
cvFindContours(imgGrayScale, storage, &contours, sizeof(CvContour), CV_RETR_LIST, CV_CHAIN_APPROX_SIMPLE, cvPoint(0,0));
//iterating through each contour
while(contours)
{cout << "contours = " << endl << " " << contours << endl << endl;
//obtain a sequence of points of contour, pointed by the variable 'contour'
contours = contours->h_next;
}
cout << "contours end = " << endl << " " << contours << endl << endl;
return 0;
}




when i convert to lisp(below ...i didnt add while loop because h-next is null),  i use nested  with-foreign-slots to access the h-next member for debugging. it is  a null pointer where in the c code above the h_next member is full of data...the function does work though....it works as good as it does in c




(let* ((img (load-image "/home/w/quicklisp/dists/quicklisp/software/cl-opencv-master/images/FindingContours.png" 1))
       (img-size (get-size img))             
       (img-grayscale (create-image img-size +ipl-depth-8u+ 1))
       (storage (create-mem-storage 0))
       ( contours (create-seq +seq-eltype-point+ (cffi:foreign-type-size '(:struct cv-seq)) 
                 (cffi:foreign-type-size '(:struct cv-point)) storage)))
      (find-contours img-grayscale  storage contours 
             (cffi:foreign-type-size '(:struct cv-contour)) +retr-list+ 
             +chain-approx-simple+ (make-cv-point :x 0 :y 0))
     
      (cffi:with-foreign-slots ((h-next) 
                  contours   (:struct cv-seq))
    
    (cffi:with-foreign-slots ((h-next) 
                  h-next (:struct cv-seq))
     
            h-next)
    
          ))


just outputs a null-pointer>> #.(SB-SYS:INT-SAP #X00000000)

any help on this would be appreciated?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mailman.common-lisp.net/pipermail/cffi-devel/attachments/20131007/8c02dd6e/attachment.html>


More information about the cffi-devel mailing list