わかりました、このtranslate-from-foreignメソッドを試してみましたが、うまくいきました。これらはライブラリのstructs.lispファイルで定義されており、他のすべての依存関係の前に最初にロードされます
(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、get-size と create-image の私の opencv ラッパーは、次のように定義されています。
;; 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 の定義です
(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
でも私は translate-foreign defmethod のアイデアが大好きです
だから私はあなたが私のライブラリを本当に素晴らしいものにする方法から以下の外国語への翻訳バージョンを作る方法を示すことができるかどうか疑問に思っていました
(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))))
私は何かを試して追加するつもりでしたが、get-size 出力構造の場合、それは plist ではないので、何をそこに置くべきか本当にわかりません
(let ((plist (call-next-method)))
一部、
(make-size :width (getf plist 'width)
:height (getf plist 'height))))
一部、 size->64 関数以外の別の方法を見つけたいと思っていました。これは、cl-opencv https://github.com/ryepup/cl-opencvが最初に出た2年前に作成されたものであり、作成したいそれよりも優れたラッパー...私はすでに cl-opencv を使用して、100 個の新しい関数、5000 行のコード サンプルとドキュメント、および新しい structs.lisp ファイルを追加しました。だから私はint64以外のことをすることができました...さらに、int64がうまくいかない場所をラップする関数があれば、準備ができています
SO のすべての回答者に感謝します。皆さんは本当に私のライブラリを大きく助けてくれました。
編集
わかりました、マデイラ氏としてすべてを以下のように定義したと思います(replセッションを示します)
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]
私が持っているtranslate-from-foreign関数は、cv-sizeからの出力を構造体に変換しているためです
CL-OPENCV> img-size
#S(SIZE :WIDTH 640 :HEIGHT 480)
translate-in-to-foreign 関数には感謝していますが、古い translate-from-foreign 関数では、make-size 部分のために機能しません... cvCreateImage がそれを満たすために必要なものを理解するのを手伝ってくれませんか ....これがリンク4です:
http://docs.opencv.org/modules/core/doc/old_basic_structures.html?highlight=eimage#createimage
以下のこのバージョンを取得して正しく実行できます(replセッションを表示します)
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によってcv-size poiner出力を逆参照できる必要があるため、これは正しい方法のようには見えません
ここに cvGetSize 関数 im ラッピングに関するドキュメントがあります
http://docs.opencv.org/modules/core/doc/old_basic_structures.html?highlight=eimage#getsize
あなたが見ることができるように、それはポインタです
CL-OPENCV> img-size
#.(SB-SYS:INT-SAP #X1E000000280)
だから私がするとき:
(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-arefing しようとすると、未処理のメモリ障害エラーが発生します
互換性のある書き込み方法を理解するのを手伝ってもらえれば
外国語からの翻訳
と
translate-to-foreign 関数私は非常に感謝しています =)。
しかし、make-size または size-width,height をそれらのどこでも使用する場合、create-image には size->int64 が含まれている必要があります。