我如何为此cffi:translate-from-foreign写一个类似的cffi:translate-to到外国defmethod? [英] How do i write a comparable cffi:translate-into foreign defmethod for this cffi:translate-from-foreign?

查看:73
本文介绍了我如何为此cffi:translate-from-foreign写一个类似的cffi:translate-to到外国defmethod?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

好吧,我尝试了这种外部翻译方法,它确实起作用了
我在我的库的structs.lisp文件中定义了这些文件,该文件首先加载所有其他依赖项

ok I tried this translate-from-foreign method and it did work I have these defined in my structs.lisp file in my library which loads first before all my other dependencies

(cffi:defcstruct (cv-size :class cv-size-type)
  (width :int)
  (height :int))

(defmethod cffi:translate-from-foreign (p (type cv-size-type))
  (let ((plist (call-next-method)))
    (make-size :width (getf plist 'width)
               :height (getf plist 'height))))

以及我的CvGetSize和cvCreateImage的opencv包装器(获取尺寸和创建图像)的定义如下:

and my opencv wrappers for CvGetSize and cvCreateImage, get-size and create-image, are defined like this

;; CvSize cvGetSize(const CvArr* arr)
 (cffi:defcfun ("cvGetSize" get-size) (:struct cv-size)
   (arr cv-arr))

 ;; IplImage* cvCreateImage(CvSize size, int depth, int channels)
 (cffi:defcfun ("cvCreateImage" %create-image) ipl-image
   (size :int64)
   (depth :int)
   (channels :int))

 (defun create-image (size depth channels)
   "Create an image with dimensions given by SIZE, DEPTH bits per
 channel, and CHANNELS number of channels."
   (let ((nsize (size->int64 size)))
     (%create-image nsize depth channels)))

这是size-> int64

here is the definition of size->int64

(DEFUN SIZE->INT64 (S) (+ (SIZE-WIDTH S) (ASH (SIZE-HEIGHT S) 32)))

 it converts get-size output which is a structure here:

#S(SIZE :WIDTH 640 :HEIGHT 480)

into 64-bit integer, which CFFI can handle 

但是我喜欢异国翻译方法的想法

but I love the idea of the translate-foreign defmethod's

想知道您是否可以告诉我如何制作belo的翻译成外国版本w from method这真的会让我的图书馆很棒

so I was wondering if you can show my how to make the translate-into-foreign version of the below from method this would really make my library awesome

(defmethod cffi:translate-from-foreign (p (type cv-size-type))
  (let ((plist (call-next-method)))
    (make-size :width (getf plist 'width)
               :height (getf plist 'height))))

我打算尝试将其添加,但是对于获取尺寸的输出结构,它不是plist,所以不太确定

I was going to try stuff and add it but for the get-size output structure, it isn't a plist so not really sure what to put there for the

(let ((plist (call-next-method)))

部分,对于

  (make-size :width (getf plist 'width)
               :height (getf plist 'height))))

部分,我希望找到size-> 64函数以外的另一种方法,因为它是2年前cl-opencv https://github.com/ryepup/cl-opencv 首先出现,我想制作
一个偶数比那个更好的包装器...我已经接受了cl-opencv添加了100个新功能5000行代码示例和文档以及一个新的structs.lisp文件,所以我希望有人可以帮助我使用所有最新的cffi工具,所以我可以做除int64之外的其他事情...再加上如果我有一个包装可以使int64无法正常工作的地方的函数,请准备好

part, I was hoping to find another method other than the size->64 function because that was made 2 years ago when cl-opencv https://github.com/ryepup/cl-opencv first came out and I would like to make an even better wrapper than that... I've already taken cl-opencv added 100 new function 5000 lines of code samples and documentation and a new structs.lisp file so I would love if someone could help me with all the latest cffi tools so I could do something else than int64...plus the if I have a function to wrap where the int64 thing wouldn't work ill be ready

再次感谢所有答复者如此

Thanks again to all the answerers on S.O. you all really have helped my library great.

编辑

好,我想我为您定义了一切,马德拉先生如下所示(我显示了repl会话)

Ok I think I defined everthing as you Mr Madeira as below (i show the repl session)

 CL-OPENCV> 
 ;; (cffi:foreign-type-size '(:struct cv-size)) = 8
 (cffi:defcstruct (cv-size :class cv-size-type)
   (width :int)
   (height :int))



 (defmethod cffi:translate-from-foreign (p (type cv-size-type))
   (let ((plist (call-next-method)))
     (make-size :width (getf plist 'width)
                :height (getf plist 'height))))

 (defmethod cffi:translate-to-foreign (value (type cv-size-type))
   (let ((plist ()))
     (setf (getf plist 'width) (size-width value)
           (getf plist 'height) (size-height value))
     (call-next-method plist type)))



 ;; CvSize cvGetSize(const CvArr* arr)
 (cffi:defcfun ("cvGetSize" get-size) (:struct cv-size)
   (arr (:pointer cv-arr)))


 ;; IplImage* cvCreateImage(CvSize size, int depth, int channels)
 (cffi:defcfun ("cvCreateImage" create-image) (:pointer (:struct  ipl-image))
   (size (:struct cv-size))
   (depth :int)
   (channels :int))


 STYLE-WARNING: redefining CL-OPENCV:GET-SIZE in DEFUN
 STYLE-WARNING: redefining CL-OPENCV:CREATE-IMAGE in DEFUN
 CREATE-IMAGE
 CL-OPENCV> (defparameter capture (create-camera-capture 0))
 (defparameter frame (query-frame capture))
 (defparameter img-size (get-size frame))
 (defparameter img (create-image img-size +ipl-depth-8u+ 3))

但出现错误

There is no applicable method for the generic function
  #<STANDARD-GENERIC-FUNCTION
    CFFI:TRANSLATE-INTO-FOREIGN-MEMORY (5)>
when called with arguments
  (#S(SIZE :WIDTH 640 :HEIGHT 480) #<CV-SIZE-TYPE CV-SIZE>
   #.(SB-SYS:INT-SAP #X7FFFE5427FF0)).
   [Condition of type SIMPLE-ERROR]

因为从外部翻译函数I已经将cv-size
的输出转换为结构

because the translate-from-foreign function I have is converting the output from cv-size into a structure

CL-OPENCV> img-size
#S(SIZE :WIDTH 640 :HEIGHT 480)

转换为外部函数,但使用旧的外部转换函数,由于make-size部分,它无法正常工作...您是否能帮助我找出cvCreateImage需要满足的条件....链接4:

I appreciate the translate-into foreign function but with the old translate-from-foreign function it isn't woking, because of the make-size part...would you help me figure out what cvCreateImage needs to satisfy it ....here is the link 4 that:

http://docs.opencv.org/modules/core/doc/old_basic_structures.html?highlight=eimage#createimage

我可以在下面获得该版本的运行权(我显示了repl会话)

I can get this version below to run right(i show the repl session)

 5
 CL-OPENCV> ; TODO SIZE-WIDTH AND HEIGHT
 ;; CvSize cvGetSize(const CvArr* arr)
 (cffi:defcfun ("cvGetSize" get-size) (:pointer (:struct cv-size))
   (arr cv-arr))


 ;; IplImage* cvCreateImage(CvSize size, int depth, int channels)
 (cffi:defcfun ("cvCreateImage" create-image) (:pointer (:struct ipl-image))
   (size (:pointer (:struct cv-size)))
   (depth :int)
   (channels :int))

 STYLE-WARNING: redefining CL-OPENCV:GET-SIZE in DEFUN
 STYLE-WARNING: redefining CL-OPENCV:CREATE-IMAGE in DEFUN
 CREATE-IMAGE
 CL-OPENCV> (defparameter capture (create-camera-capture 0))
 (defparameter frame (query-frame capture))
 (defparameter img-size (get-size frame))
 (defparameter img (create-image img-size +ipl-depth-8u+ 3))
 IMG
 CL-OPENCV> (cffi:with-foreign-slots ((n-size id n-channels 
                           alpha-channel depth color-model 
                           channel-seq data-order origin  
                           align width height roi 
                           mask-roi image-id tile-info 
                           image-size image-data width-step 
                           border-mode border-const image-data-origin) 

                           img(:struct ipl-image))
                           (format t "n-size = ~a~%id = ~a~%n-channels = ~a~%alpha-channel = ~a~%depth = ~a~%color-model = ~a~%channel-seq = ~a~%data-order = ~a~%origin = ~a~%align = ~a~%width = ~a~%height = ~a~%roi = ~a~%mask-roi = ~a~%image-id = ~a~%tile-info = ~a~%image-size = ~a~%image-data = ~a~%width-step = ~a~%border-mode = ~a~%border-const = ~a~%image-data-origin = ~a~%" 
                           n-size id n-channels 
                           alpha-channel depth color-model 
                           channel-seq data-order origin  
                           align width height roi 
                           mask-rOI image-id tile-info 
                           image-size image-data width-step 
                           border-mode border-const image-data-origin))
 n-size = 144
 id = 0
 n-channels = 3
 alpha-channel = 0
 depth = 8
 color-model = 4343634
 channel-seq = 5392194
 data-order = 0
 origin = 0
 align = 4
 width = 640
 height = 480
 roi = #.(SB-SYS:INT-SAP #X00000000)
 mask-roi = #.(SB-SYS:INT-SAP #X00000000)
 image-id = #.(SB-SYS:INT-SAP #X00000000)
 tile-info = #.(SB-SYS:INT-SAP #X00000000)
 image-size = 921600
 image-data = 
 width-step = 1920
 border-mode = #.(SB-SYS:INT-SAP #X00000000)
 border-const = #.(SB-SYS:INT-SAP #X00000000)
 image-data-origin = NIL
 NIL

所以我从插槽中获取了用于ipl-image的数据,但这似乎不是正确的方法
,因为id必须能够通过get-size

so I get data from the slots for ipl-image but this does'nt seem like correct way because id have to be able to derefrence the cv-size poiner output by get-size

这是有关cvGetSize的文档,功能是包装

here is documentation on cvGetSize the function im wrapping

http://docs.opencv.org/modules/core/doc/old_basic_structures.html?highlight=eimage#getsize

如您所见,它是一个指针

as u can see it is a pointer

CL-OPENCV> img-size
#.(SB-SYS:INT-SAP #X1E000000280)

so当我这样做时:

  (cffi:with-foreign-object (img-size '(:pointer (:struct cv-size)))
            ;; Initialize the slots

            ;; Return a list with the coordinates
            (cffi:with-foreign-slots ((width height) img-size 

              (list width height)))

我知道

 There is no applicable method for the generic function
   #<STANDARD-GENERIC-FUNCTION CFFI::SLOTS (1)>
 when called with arguments
   (#<CFFI::FOREIGN-POINTER-TYPE (:POINTER (:STRUCT CV-SIZE))>).
    [Condition of type SIMPLE-ERROR]     

当我这样做

 (cffi:with-foreign-object (img-size '(:struct cv-size))
      ;; Initialize the slots

      ;; Return a list with the coordinates
      (cffi:with-foreign-slots ((width height) img-size (:struct cv-size))
        (list width height)))

我得到

(346539 0)

只是无意义的输出

我尝试使用mem-refing和mem-arfing指针,并得到未处理的内存错误错误

I try mem-refing and mem-arefing the pointer and get unhandled memory fault errors

如果可以帮助我找出原因如何编写兼容的

if you can help me figure out how to write compatible

从国外翻译

将其转换为外部函数,我将不胜感激=)。

translate-into-foreign functions I would be very grateful =).

但是如果我使用make-size或size-width,它们中的任何地方都为高度创建图像必须具有size-> int64,因为它们仅由于该功能而起作用。

but if I use make-size or size-width,height anywhere in them the create-image would have to have the size->int64 in it because they work only because that function.

推荐答案

是与 translate-from-foreign 方法定义完全相反的定义。我目前无法测试,但是您可能想尝试一下是否可行:

This should be the exact reverse definition to your translate-from-foreign method definition. I can't test it right now, but you might want to try if it works:

(defmethod cffi:translate-to-foreign (value (type cv-size-type))
  (let ((plist ()))
    (setf (getf plist 'width) (size-width value)
          (getf plist 'height) (size-height value))
    (call-next-method plist type)))

正如其他答案正确指出的那样,您绝对必须在 defcfun 中将 size 的类型更改从:int64 (:struct cv-size),否则将不会调用此方法。

As the other answer correctly points out, you definitely must change the type for size in the defcfun from :int64 to (:struct cv-size), otherwise this method won't be called.

这篇关于我如何为此cffi:translate-from-foreign写一个类似的cffi:translate-to到外国defmethod?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆