我正在将Lightweight Communications and Marshalling从julia移植到lisp,因为它具有更好的API。我使用swig来生成C函数调用。
我想知道这是否是C指针的安全用法。这是创建函数:
(defun create-lcm (&optional (provider (null-pointer)))
(let* ((ptr (lcm_create provider))
(addr (cffi:pointer-address ptr)))
(tg:finalize ptr (lambda () (lcm_destroy (cffi:make-pointer addr))))
(if (NULL-POINTER-P ptr)
(error "lcm creation error"))
(%create-lcm :pointer ptr :provider provider
:file-descriptor (lcm_get_fileno ptr))))
问题:
欢迎其他任何注释/建议。
谢谢。
答案 0 :(得分:3)
有些错误的地方:
我不知道这是对的,但是更好:
(defun create-lcm (&optional (provider (null-pointer))
(let ((ptr (lcm_create provider)))
(when (null-pointer-p ptr)
(error “lcm creation error”))
(flet ((finaliser () (lcm_destroy ptr)))
(let ((result (%create-lcm :pointer ptr :provider provider
:file-descriptor (lcm_get_fileno ptr))))
(tg:finalize result #'finaliser)
result))))
有些错误的地方:
%create-lcm
或lcm_get_fileno
出现错误,则终结器将无法运行答案 1 :(得分:3)
您可能想了解有关cl-autowrap
的知识,该知识特别用于将 SDL 2 包装在cl-sdl2
中。该库提供了围绕指针的精简包装器,这些指针已经在完成时释放了内存。
我还认为,建议使用终结器的方法仅是使用它们来清理可能的泄漏,因为您几乎无法控制何时以及如何执行清理功能(例如,哪个线程,哪个动态环境)。 / p>
一种管理内存的方法是提前分配结构,并在不再需要它们时清理它们(池)。或者,您可以定义一个函数或宏来定义范围,以便使用unwind-protect在进入内存时分配内存并在退出时释放内存:
(defmacro with-lcm ((context &rest options) &body body)
(let ((internal (gensym)))
`(let* ((,internal (create-lcm ,@options))
(,context ,internal))
(unwind-protect (progn ,@body)
(destroy-lcm ,internal)))))