2016-01-07 8 views
1

родного гр заголовка:Как звонить родную функцию С с окном HANDLE в общей LISP/cffi

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

HANDLE определяются:

typedef void *HANDLE; 

родной источник с я хочу:

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

Я пробовал следующий код в sbcl 1.3.1, но не работал.

(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*)) 

КСТАТИ: КАК ПОЛУЧИТЬ АДРЕС ИНОСТРАННОЙ ОБЪЕКТ (камеры)? Я делаю это правильно?

ответ

1

Вы можете получить адрес, как это:

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

Если у вас есть этот файл C

#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; 
}; 

вы можете увидеть, например, по этому общему файлу lisp, вы получите тот же адрес из lisp и C для handle. Это не то же самое для *camera*, потому что оно передается по значению. Я попробовал это на Linux, но я думаю, что это должно быть то же самое в Windows, просто измените camera.so на 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) 

Возможной ловушка: Если я использую этот код на Лисп из Emacs, я не вижу стандартный вывод из C. Я выполнил его из командной строки с sbcl --script file.lisp. Надеюсь, это вам поможет.

+0

Спасибо Zalkow. –

0

я, наконец, понял, используя следующий код:

(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))))