How to call native c function with HANDLE windows in general lisp / cffi

native c header:

typedef HANDLE HCAMERA; int Begin(HCAMERA* h); int End(HCAMERA h); 

HANDLE is defined:

 typedef void *HANDLE; 

native c source I want:

 HCAMERA h; int r = 0; r = Begin(&h); VERIFY(r); r = End(h); VERIFY(r); 

I tried the following code in sbcl 1.3.1 but did not work.

 (cffi:use-foreign-library "camera.dll") (cffi:defcfun "Begin" :int (handle :pointer)) (cffi:defcfun "End" :int (handle :pointer)) (defparameter *camera* (cffi:foreign-alloc :pointer)) ; alloc handle (cffi:with-foreign-object (handle :pointer) (setf (cffi:mem-ref handle :pointer) *camera*) ; handle address (Begin handle) (End *camera*)) 

By the way: HOW TO GET THE ADDRESS OF A FOREIGN OBJECT (camera)? Am I doing it right?

+1
source share
2 answers

You can get the address as follows:

 (defun get-foreign-address (obj) (write-to-string (cffi:pointer-address obj) :base 16)) 

If you have this C file

 #include <stdio.h> typedef void *HANDLE; typedef HANDLE HCAMERA; int Begin(HCAMERA* h); int End(HCAMERA h); int Begin(HCAMERA* h) { printf("Address from Begin: %p\n", h); return 0; }; int End(HCAMERA h) { printf("Address from End: %p\n", (void*)&h); return 0; }; 

you can see for example. in this generic lisp file, you will get the same address from lisp and C for handle . This is not the same for *camera* because it is passed by value. I tried this on Linux, but I think it should be the same on Windows, just change camera.so to camera.dll .

 (cffi:use-foreign-library "camera.so") (cffi:defcfun "Begin" :int (handle :pointer)) (cffi:defcfun "End" :int (handle :pointer)) (cffi:defcvar ("stdout" stdout) :pointer) (defparameter *camera* (cffi:foreign-alloc :pointer)) (cffi:with-foreign-object (handle :pointer) (format t "Address from Lisp: ~a~%" (get-foreign-address handle)) (Begin handle) (format t "Address from Lisp: ~a~%" (get-foreign-address *camera*)) (End *camera*)) (cffi:foreign-funcall "fflush" :pointer stdout :int) 

Possible error: if I use this lisp code from Emacs, I cannot see stdout from C. I executed it from the command line using sbcl --script file.lisp . Hope this helps you.

+1
source

I finally understood using the following code:

 (defparameter *camera-handle* (cffi:null-pointer)) (defun camera-open () (unless (cffi:null-pointer-p *camera-handle*) (EndHVDevice (cffi:mem-ref *camera-handle* :pointer)) (cffi:foreign-free *camera-handle*)) (setf *camera-handle* (cffi:foreign-alloc :pointer)) (BeginHVDevice *camera-handle*)) (defun camera-close () (unless (cffi:null-pointer-p *camera-handle*) (EndHVDevice (cffi:mem-ref *camera-handle* :pointer)) (cffi:foreign-free *camera-handle*) (setf *camera-handle* (cffi:null-pointer)))) 
0
source

Source: https://habr.com/ru/post/1244570/


All Articles