Page 1 of 1

How do i use Lisp/CFFI's defcunion?

Posted: Tue Oct 01, 2013 3:04 am
by joeish80829
I'm trying to convert a c union call into lisp....

here is the function I'm trying to convert::

float sum( const CvMat* mat ) {
float s = 0.0f;
for(int row=0; row<mat->rows; row++ ) {
const float* ptr = (const float*)(mat->data.ptr + row * mat->step);
for( col=0; col<mat->cols; col++ ) {
s += *ptr++;
}
}
return( s );
}

the union call is here..

mat->data.ptr

i wrapped the opencv core types_c.h where the the CvMat struct and union are declared

here they are:

typedef struct CvMat
{
int type;
int step;

/* for internal use only */
int* refcount;
int hdr_refcount;

union
{
uchar* ptr;
short* s;
int* i;
float* fl;
double* db;
} data;

#ifdef __cplusplus
union
{
int rows;
int height;
};

union
{
int cols;
int width;
};
#else
int rows;
int cols;
#endif

}
CvMat;

when i wrap the types_c.h with swig it outputs the below 2 items for the above:

;; Had to change from SWIG - put data above rows and cols....was below
;; ;(cffi:foreign-type-size '(:struct cv-mat)) = 40
(cffi:defcstruct cv-mat
(type :int)
(step :int)
(refcount :pointer)
(hdr_refcount :int)
(data :pointer)
(rows :int)
(cols :int))

(cffi:defcunion CvMat_data
(ptr :pointer)
(s :pointer)
(i :pointer)
(fl :pointer)
(db :pointer))

when i try and run the defcstruct as:

(cffi:defcstruct cv-mat
(type :int)
(step :int)
(refcount :pointer)
(hdr_refcount :int)
(data (:union CvMat_data))
(rows :int)
(cols :int))

it runs with the defcunion already loaded

so i do this to access the structs slots as a test /with output:

CL-OPENCV> (defparameter mat (create-mat 3 3 +32fc1+))
MAT
CL-OPENCV> (cffi:with-foreign-slots ((type rows cols step hdr_refcount refcount) mat (:struct cv-mat))
(list type rows cols step hdr_refcount refcount))
output> (1111638016 3 3 3 1 #.(SB-SYS:INT-SAP #X7FFFD824C4C0))
CL-OPENCV>

the same call in c outputs:

cout << "type =" << endl << " " << m->type << endl << endl;
cout << "step =" << endl << " " << m->step << endl << endl;
cout << "refcount =" << endl << " " << m->refcount << endl << endl;
cout << "hdr_refcount =" << endl << " " << m->hdr_refcount << endl << endl;
cout << "rows =" << endl << " " << m->rows << endl << endl;
cout << "M = " << endl << " " << m->cols << endl << endl;

type =
1111638016

step =
3

refcount =
0x2332100

hdr_refcount =
1

rows =
3

M =
3

so everything appears even struct wise

by the way my create-mat wrapper is defined as

;; CvMat* cvCreateMat(int rows, int cols, int type)
(cffi:defcfun ("cvCreateMat" create-mat) (:pointer (:struct cv-mat))
(rows :int)
(cols :int)
(type :int))

so i set data to the matrix and acess the elements so you can see data is there:

CL-OPENCV> (defparameter data (cffi:foreign-alloc :float :initial-contents
'(0.0f0 1.0f0 2.0f0 3.0f0 4.0f0 5.0f0 6.0f0 7.0f0 8.0f0)))
DATA
CL-OPENCV> (set-data mat data 12)
; No value
CL-OPENCV> (get-real-2d mat 0 0 )
0.0d0
CL-OPENCV> (get-real-2d mat 0 1 )
1.0d0
CL-OPENCV> (get-real-2d mat 0 2 )
2.0d0

so i attempt to access the data slot of my defcstruct like this and get below error:

(cffi:with-foreign-slots ((data type rows cols
step hdr_refcount refcount) mat (:struct cv-mat))
(list data type rows cols step hdr_refcount refcount))


Execution of a form compiled with errors.
Form:
(SYMBOL-MACROLET ((DATA
(CFFI:FOREIGN-SLOT-VALUE #1=#:PTR1299 '#2=(:STRUCT CV-MAT)
'DATA))
(TYPE (CFFI:FOREIGN-SLOT-VALUE #1# '#2# 'TYPE))
(ROWS (CFFI:FOREIGN-SLOT-VALUE #1# '#2# 'ROWS))
(COLS (CFFI:FOREIGN-SLOT-VALUE #1# '#2# 'COLS))
(STEP (CFFI:FOREIGN-SLOT-VALUE #1# '#2# 'STEP))
(HDR_REFCOUNT
(CFFI:FOREIGN-SLOT-VALUE #1# '#2# 'HDR_REFCOUNT))
(REFCOUNT (CFFI:FOREIGN-SLOT-VALUE #1# '#2# 'REFCOUNT)))
(LIST DATA TYPE ROWS COLS STEP HDR_REFCOUNT REFCOUNT))
Compile-time error:
Attempt to bind a special variable with SYMBOL-MACROLET: DATA
[Condition of type SB-INT:COMPILED-PROGRAM-ERROR]

so i try(with the (:union) quoted and unquoted):

(cffi:with-foreign-slots ((data type rows cols step hdr_
refcount refcount) mat '(:union CvMat_data))
(list data type rows cols step hdr_refcount refcount))

and get same above error both with string quoted and unquoted the PTR1299 part of error increments 1 number each time

so if anyone can teach me how 2 do this i would be much appreciative...