Joeish W joeish80829@yahoo.com writes:
Lisp code is here https://gist.github.com/W-Net-AI/11205892 ... LCV> (dotimes (ic (vector-rect-size faces)) (setf n (%vector-rect-to-c-array faces)) (rect-x (mem-aref n :pointer ic)))
this is where it fails, rect-x, my Lisp wrapper for C wrapper for the c++ Rect class member x in this statement isn't getting a Rect* so it outputs error: Unhandled ;memory fault at #xC9000000D5. The %vector-rect-to-c-array function is a wrapper for the c function in the posted c/c++ code. It works as expected on everything else but the vector<Rect> output of detectMultiScale.
This fails because `n` is a pointer the data of vector<Rect>. So it points to an array of Rect structures, NOT an array of Rect* (pointers to Rect).
What would work (but I am advising against this), is:
(rect-x (inc-pointer n (* ic SIZE_OF_RECT)))
Where SIZE_OF_RECT is the size of the Rect struct.
What you should do is look into `defcstruct` to properly wrap the Rect struct and start from there.
Wim Oudshoorn.
Thank you very much for all the help recently, actually the Rect is a OpenCv C class here: http://docs.opencv.org/trunk/modules/core/doc/basic_structures.html?highligh... your advice on making a defcstruct for it stand..Remember, the same code works evaluating the same way at the REPL creating a vector<Rectt> like this:
Functions:
;; template < class T, class Alloc = allocator<T> > class vector ;; vector_##t * carray_to_std_vector##tn( t * a, size_t len ) (defcfun ("carray_to_std_vectorr" %c-arr-to-vector-rect) (:pointer vector-rect) (a :pointer) (len :unsigned-int))
;; template < class T, class Alloc = allocator<T> > class vector ;; t * std_vector##tn##_to_carray( vector_##t * v ) (defcfun ("std_vectorr_to_carray" %vector-rect-to-c-array) (:pointer rect) (s (:pointer vector-rect)))
(%c-arr-to-vector-rect (foreign-alloc :pointer :initial-contents (list (rect 1 2 3 4) (rect 5 6 7 8))) 2)
VECTOR-RECT-SIZE just gets the size of the vector
(dotimes (ic (%vector-rect-size faces)) (setf n (%vector-rect-to-c-array faces)) (format t "~a~%" (rect-x (mem-aref n :pointer ic)))) ; ; caught WARNING: ; undefined variable: N ; ; compilation unit finished ; Undefined variable: ; N ; caught 1 WARNING condition 1 <-- both x values 5
On Saturday, April 26, 2014 4:41 AM, Willem Rein Oudshoorn woudshoo@xs4all.nl wrote:
Joeish W joeish80829@yahoo.com writes:
Lisp code is here https://gist.github.com/W-Net-AI/11205892 ... LCV> (dotimes (ic (vector-rect-size faces)) (setf n (%vector-rect-to-c-array faces)) (rect-x (mem-aref n :pointer ic)))
this is where it fails, rect-x, my Lisp wrapper for C wrapper for the c++ Rect class member x in this statement isn't getting a Rect* so it outputs error: Unhandled ;memory fault at #xC9000000D5. The %vector-rect-to-c-array function is a wrapper for the c function in the posted c/c++ code. It works as expected on everything else but the vector<Rect> output of detectMultiScale.
This fails because `n` is a pointer the data of vector<Rect>. So it points to an array of Rect structures, NOT an array of Rect* (pointers to Rect).
What would work (but I am advising against this), is:
(rect-x (inc-pointer n (* ic SIZE_OF_RECT)))
Where SIZE_OF_RECT is the size of the Rect struct.
What you should do is look into `defcstruct` to properly wrap the Rect struct and start from there.
Wim Oudshoorn.
Cffi-devel mailing list Cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W joeish80829@yahoo.com writes:
Thank you very much for all the help recently, actually the Rect is a OpenCv C class here: http://docs.opencv.org/trunk/modules/core/doc/basic_structures.html?highligh... your advice on making a defcstruct for it stand..
Hm, maybe not. But I do not know exactly what you need to do.
Remember, the same code works evaluating the same way at the REPL creating a vector<Rectt> like this:
Functions:
;; template < class T, class Alloc = allocator<T> > class vector ;; vector_##t * carray_to_std_vector##tn( t * a, size_t len ) (defcfun ("carray_to_std_vectorr" %c-arr-to-vector-rect) (:pointer vector-rect) (a :pointer) (len :unsigned-int))
It helps if you include or points to the C-functions carray_to_std_vectorr and std_vectorr_to_carray, because now I have to guess what they do.
[Some code omitted]
(%c-arr-to-vector-rect (foreign-alloc :pointer :initial-contents (list (rect 1 2 3 4) (rect 5 6 7 8))) 2)
I am assuming `rect` is a function which calls a defcfun wrapper to create a Rect.
VECTOR-RECT-SIZE just gets the size of the vector
(dotimes (ic (%vector-rect-size faces)) (setf n (%vector-rect-to-c-array faces)) (format t "~a~%" (rect-x (mem-aref n :pointer ic)))) ; ; caught WARNING: ; undefined variable: N ; ; compilation unit finished ; Undefined variable: ; N ; caught 1 WARNING condition 1 <-- both x values 5
Yes, this works. However most likely not in the way you think it does. I think the following is happening:
1. The call to %c-arr-to-vector-rect gets two arguments: a. A pointer to a block of memory containging two pointers to instances of Rect.
Argument 1: ----> [pointer a | pointer b ] --> [RECT: 5 6 7 8] | v [RECT: 1 2 3 4]
Argument 2: 2
2. The function `carray_to_std_vectorr` takes these two arguments to do the following:
a. Create an array of 2 rectangles like this:
[ [RECT: * * * *] | [RECT: * * * *] ]
b. Copies the content of Argument 1 into this array:
[ [RECT: pointer a pointer b * *] | [RECT: * * * *]]
c. Returns the pointer to a vector wrapping the array constructed above.
Now you can see that the constructed vector<Rect> is garbage. But when you retrieve in lisp the values of this array you assume that the array is an array of pointers. And as such it ignores it should be RECTs and just sees two pointers, pointer a and pointer b.
Now your `rect-x` expects pointers and therefore it works.
So it does work, but only because both mistakes (when creating the vector and when reading the vector) cancel each other out. If you use the array of rectangles in the OpenCV API, the OpenCV code will see garbage.
(Note I cannot see all the code, because you give snippets without the underlying C-code and data structures, so I cannot be absolutely sure but I am pretty confident that this is what is going on.)
Wim Oudshoorn.
This is important to figure out so I thought I'd include the contents of my C++ interop.cpp file in a gist https://gist.github.com/W-Net-AI/11319737%C2%A0 and my rect.cpp W-Net-AI/gist:11319776 you have my Lisp vector class wrappers so here is my Lisp rect wrappers...the rect is a little involved for the purpose of overloading.
;; Rect_() ;; Rect* cv_create_Rect() (defcfun ("cv_create_Rect" rect0) (:pointer mat) "RECT constructor.") ;; Rect_(_Tp _x, _Tp _y, _Tp _width, _Tp _height) ;; Rect* cv_create_Rect4(int x, int y, int width, int height) (defcfun ("cv_create_Rect4" rect4) (:pointer rect) "RECT constructor." (x :int) (y :int) (width :int) (height :int)) (defun rect (&optional x y width height) (cond ((eq (or x y) nil) (rect0)) ((and x y) (rect4 x y width height)) (t nil)))
this is the rect-x i have been using:
;; _Tp x, y, width, height ;; int cv_Rect_getX(Rect* self) (defcfun ("cv_Rect_getX" rect-x) :int (self (:pointer rect)))
W-Net-AI/gist:11319776 - Gist is a simple way to share snippets of text and code with others. View on gist.github.com Preview by Yahoo On Saturday, April 26, 2014 6:06 AM, Willem Rein Oudshoorn woudshoo@xs4all.nl wrote:
Joeish W joeish80829@yahoo.com writes:
Thank you very much for all the help recently, actually the Rect is a OpenCv C class here: http://docs.opencv.org/trunk/modules/core/doc/basic_structures.html?highligh... your advice on making a defcstruct for it stand..
Hm, maybe not. But I do not know exactly what you need to do.
Remember, the same code works evaluating the same way at the REPL creating a vector<Rectt> like this:
Functions:
;; template < class T, class Alloc = allocator<T> > class vector ;; vector_##t * carray_to_std_vector##tn( t * a, size_t len ) (defcfun ("carray_to_std_vectorr" %c-arr-to-vector-rect) (:pointer vector-rect) (a :pointer) (len :unsigned-int))
It helps if you include or points to the C-functions carray_to_std_vectorr and std_vectorr_to_carray, because now I have to guess what they do.
[Some code omitted]
(%c-arr-to-vector-rect (foreign-alloc :pointer :initial-contents (list (rect 1 2 3 4) (rect 5 6 7 8))) 2)
I am assuming `rect` is a function which calls a defcfun wrapper to create a Rect.
VECTOR-RECT-SIZE just gets the size of the vector
(dotimes (ic (%vector-rect-size faces)) (setf n (%vector-rect-to-c-array faces)) (format t "~a~%" (rect-x (mem-aref n :pointer ic)))) ; ; caught WARNING: ; undefined variable: N ; ; compilation unit finished ; Undefined variable: ; N ; caught 1 WARNING condition 1 <-- both x values 5
Yes, this works. However most likely not in the way you think it does. I think the following is happening:
- The call to %c-arr-to-vector-rect gets two arguments:
a. A pointer to a block of memory containging two pointers to instances of Rect.
Argument 1: ----> [pointer a | pointer b ] --> [RECT: 5 6 7 8] | v [RECT: 1 2 3 4]
Argument 2: 2
- The function `carray_to_std_vectorr` takes these two arguments to do
the following:
a. Create an array of 2 rectangles like this:
[ [RECT: * * * *] | [RECT: * * * *] ]
b. Copies the content of Argument 1 into this array:
[ [RECT: pointer a pointer b * *] | [RECT: * * * *]]
c. Returns the pointer to a vector wrapping the array constructed above.
Now you can see that the constructed vector<Rect> is garbage. But when you retrieve in lisp the values of this array you assume that the array is an array of pointers. And as such it ignores it should be RECTs and just sees two pointers, pointer a and pointer b.
Now your `rect-x` expects pointers and therefore it works.
So it does work, but only because both mistakes (when creating the vector and when reading the vector) cancel each other out. If you use the array of rectangles in the OpenCV API, the OpenCV code will see garbage.
(Note I cannot see all the code, because you give snippets without the underlying C-code and data structures, so I cannot be absolutely sure but I am pretty confident that this is what is going on.)
Wim Oudshoorn.
Cffi-devel mailing list Cffi-devel@common-lisp.net http://common-lisp.net/cgi-bin/mailman/listinfo/cffi-devel
Joeish W joeish80829@yahoo.com writes:
This is important to figure out so I thought I'd include the contents of my C++ interop.cpp file in a gist https://gist.github.com/W-Net-AI/11319737%C2%A0 and my rect.cpp W-Net-AI/gist:11319776 you have my Lisp vector class wrappers so here is my Lisp rect wrappers...the rect is a little involved for the purpose of overloading.
Well, the code for Rect will work. However:
1. Notice that you deal with pointers to Rect's.
2. You do not have a function to free the memory created by the `new Rect'
3. You really should use the type conversion like I showed you before if you want to keep your sanity.
Now your problem with the vector<Rect> code boils down to the following mismatch:
A. The vector deals with instances of Rect NOT pointers to Rect B. The other code rect code expect pointers to Rect NOT instances of RECT.
So you have two options:
i. Only deal with pointers to Rect. This means you cannot use vector<Rect> but have to use vector<Rect*>.
ii. Learn to deal with both. This will require conversion from Rect <--> Rect*.
Now note, that if you want to keep using vector<Rect> you need to either: - Translate the vector<Rect> --> vector<Rect*> <-> Rect** on the C-side - Or do it on the lisp side, but that means that CFFI/Lisp need to know the size of the Rect instances.
Wim Oudshoorn