Common lisp 代码运行在SLIME+;SBCL而非普通SBCL
我一直在尝试为CFFI绑定(:)构建一个lispy接口,但我遇到了这样一种情况:代码在SLIME中正确运行,SLIME以SBCL实例作为后端,但在我仅在SBCL中运行代码时不会运行 因此,我创建了一个测试用例文件来演示错误:Common lisp 代码运行在SLIME+;SBCL而非普通SBCL,common-lisp,hdf5,sbcl,slime,cffi,Common Lisp,Hdf5,Sbcl,Slime,Cffi,我一直在尝试为CFFI绑定(:)构建一个lispy接口,但我遇到了这样一种情况:代码在SLIME中正确运行,SLIME以SBCL实例作为后端,但在我仅在SBCL中运行代码时不会运行 因此,我创建了一个测试用例文件来演示错误: (asdf:load-system :cffi) ;;(asdf:operate 'asdf:load-op :cffi) (defpackage :hdf5test (:use :cl :cffi) (:export :test)) (in-package :
(asdf:load-system :cffi)
;;(asdf:operate 'asdf:load-op :cffi)
(defpackage :hdf5test
(:use :cl :cffi)
(:export :test))
(in-package :hdf5test)
(define-foreign-library hdf5
(t (:default "libhdf5")))
(use-foreign-library hdf5)
;; hdf types:
(defctype size-t :uint)
(defctype hid-t :int)
(defctype herr-t :int)
(defctype hsize-t :uint64)
;; hdf constants:
;; H5S_UNLIMITED: 2^64-1
(defconstant +H5S-UNLIMITED+ 18446744073709551615)
;; H5F_ACC_TRUNC
(defconstant +H5F-ACC-TRUNC+ 2) ;; we'll see if it works
;; H5P_DEFAULT
(defconstant +H5P-DEFAULT+ 0)
;; H5T types:
(defconstant +H5P-DATASET-CREATE+ 150994953)
(defconstant +H5T-NATIVE-INT+ 50331660)
;; hdf functions:
;; H5Screate_simple
(defcfun "H5Screate_simple" hid-t
(rank :int)
(current-dims :pointer) ; const hsize_t*
(maximum-dims :pointer)) ; cons hsize_t*
;; H5Fcreate
(defcfun "H5Fcreate" hid-t
(filename :string)
(flags :uint)
(fcpl-id hid-t)
(fapl-id hid-t))
;; H5Pcreate
(defcfun "H5Pcreate" hid-t
(cls-id hid-t))
;; H5Pset_chunk
(defcfun "H5Pset_chunk" herr-t
(plist hid-t)
(ndims :int)
(dim :pointer)) ;; const hsize_t*
;; H5Pset_deflate
(defcfun "H5Pset_deflate" herr-t
(plist-id hid-t)
(level :uint))
;; H5Dcreate1
(defcfun "H5Dcreate1" hid-t
(loc-id hid-t)
(name :string)
(type-id hid-t)
(space-id hid-t)
(dcpl-id hid-t))
;; H5Dclose
(defcfun "H5Dclose" herr-t
(dataset-id hid-t))
;; H5Dwrite
(defcfun "H5Dwrite" herr-t
(datset-id hid-t)
(mem-type-id hid-t)
(mem-space-id hid-t)
(file-space-id hid-t)
(xfer-plist-id hid-t)
(buf :pointer))
;; H5Fclose
(defcfun "H5Fclose" herr-t
(file-id hid-t))
;; H5Sclose
(defcfun "H5Sclose" herr-t
(space-id hid-t))
(defparameter *rank* 1)
(defun test (filename)
(with-foreign-string (dataset-name "dataset")
(with-foreign-objects ((dim :int 1)
(dataspace-maxdim :uint64 1)
(memspace-maxdim :uint64 1)
(chunkdim :int 1)
(dataspace 'hid-t)
(dataset 'hid-t)
(memspace 'hid-t)
(cparms 'hid-t))
(setf (mem-aref dim :int 0) 5)
(format t "dim: ~a~%" (mem-aref dim :int 0))
;;(setf (mem-aref maxdim :int 0) -1)
(setf (mem-aref dataspace-maxdim :uint64 0) +H5S-UNLIMITED+)
(setf (mem-aref memspace-maxdim :uint64 0) 5)
(setf (mem-aref chunkdim :int 0) 1)
(format t "dataspace-maxdim: ~a~%" (mem-aref dataspace-maxdim :uint64 0))
(format t "memspace-maxdim: ~a~%" (mem-aref memspace-maxdim :uint64 0))
;;(with-open-hdf-file (file filename :direction :output :if-exists :supersede)
(let ((file (h5fcreate filename +H5F-ACC-TRUNC+ +H5P-DEFAULT+ +H5P-DEFAULT+)))
(setf cparms (h5pcreate +H5P-DATASET-CREATE+))
(h5pset-chunk cparms *rank* chunkdim)
(setf dataspace (h5screate-simple *rank* dim dataspace-maxdim))
(setf dataset (h5dcreate1
file
dataset-name
+H5T-NATIVE-INT+
dataspace
cparms))
(format t "dataspace: ~a~%" dataspace)
(format t "dataset: ~a~%" dataset)
(setf memspace (h5screate-simple *rank* dim memspace-maxdim))
(with-foreign-object (data :int 5)
(loop for i from 0 to 4 do (setf (mem-aref data :int i) (* i i)))
(h5dwrite dataset +H5T-NATIVE-INT+ memspace dataspace +H5P-DEFAULT+ data))
(h5dclose dataset)
(h5sclose memspace)
(h5sclose dataspace)
(h5fclose file)))))
我在SLIME+SBCL中运行(hdf5test:test“test.h5”)得到的输出是
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
0
我在SBCL中运行(hdf5test:test“test.h5”)得到的输出是
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: H5S.c line 1388 in H5Screate_simple(): maxdims is smaller than dims
major: Invalid arguments to routine
minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: H5Dio.c line 233 in H5Dwrite(): not a data space
major: Invalid arguments to routine
minor: Inappropriate type
HDF5-DIAG: Error detected in HDF5 (1.8.10-patch1) thread 0:
#000: H5S.c line 405 in H5Sclose(): not a dataspace
major: Invalid arguments to routine
minor: Inappropriate type
0
因此,您可以看到这与数组如何传递给hdf函数有关,但我不知道为什么SLIME+SBCL会处理这个问题,而不是SBCL
我还尝试了与CLISP完全相同的代码,它工作正常,没有问题,因此它似乎是SBCL问题
有什么想法吗
编辑:我想我应该在主要帖子中补充一点,即在每种情况下生成的文件都是不同的。在SLIME+SBCL或CLISP中,文件包含一个有限的数据集,其中包含平方整数(实际上没有理由,只是一个测试)。但是,使用普通SBCL时,数据文件不完整;如果您尝试使用h5dump查看内容,这将是对零的无休止的尝试(这就是它处理不完整数据集的方式)。正如@nixeagle所说,slime似乎隐藏了源自hdf5库的错误消息。沿着这些思路,我敢打赌,将结果从SBCL传递到slime中的emacs是允许写入文件的原因 现在需要对以下内容稍加说明,因为我对hdf5或cffi一无所知,现在我刚刚回到common lisp,但在我的x86_64 linux机器上,当我用
:uint64
替换了所有:int
类型后,在slime和sbcl中的工作就开始保持一致了,这似乎是有道理的,因为声明无论如何都会解析为这种类型
您在sbcl中的代码:
* (load "temp.lisp")
T
* (hdf5test:test "test2.h5")
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
#000: H5S.c line 1388 in H5Screate_simple(): maxdims is smaller than dims
major: Invalid arguments to routine
minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
#000: H5Dio.c line 231 in H5Dwrite(): can't prepare for writing data
major: Dataset
minor: Write failed
#001: H5Dio.c line 332 in H5D__pre_write(): not a data space
major: Invalid arguments to routine
minor: Inappropriate type
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
#000: H5S.c line 405 in H5Sclose(): not a dataspace
major: Invalid arguments to routine
minor: Inappropriate type
0
* (load "temp.lisp")
T
* (hdf5test:test "test2.h5")
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
0
放弃改变:
(with-foreign-objects ((dim :uint64 1)
(dataspace-maxdim :uint64 1)
(memspace-maxdim :uint64 1)
(chunkdim :uint64 1)
(dataspace 'hid-t)
(dataset 'hid-t)
(memspace 'hid-t)
(cparms 'hid-t))
(setf (mem-aref dim :uint64 0) 5)
(format t "dim: ~a~%" (mem-aref dim :uint64 0))
;;(setf (mem-aref maxdim :int 0) -1)
(setf (mem-aref dataspace-maxdim :uint64 0) +H5S-UNLIMITED+)
(setf (mem-aref memspace-maxdim :uint64 0) 5)
(setf (mem-aref chunkdim :uint64 0) 1)
(format t "dataspace-maxdim: ~a~%" (mem-aref dataspace-maxdim :uint64 0))
(format t "memspace-maxdim: ~a~%" (mem-aref memspace-maxdim :uint64 0))
sbcl中更改的代码:
* (load "temp.lisp")
T
* (hdf5test:test "test2.h5")
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
#000: H5S.c line 1388 in H5Screate_simple(): maxdims is smaller than dims
major: Invalid arguments to routine
minor: Bad value
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
#000: H5Dio.c line 231 in H5Dwrite(): can't prepare for writing data
major: Dataset
minor: Write failed
#001: H5Dio.c line 332 in H5D__pre_write(): not a data space
major: Invalid arguments to routine
minor: Inappropriate type
HDF5-DIAG: Error detected in HDF5 (1.8.12) thread 0:
#000: H5S.c line 405 in H5Sclose(): not a dataspace
major: Invalid arguments to routine
minor: Inappropriate type
0
* (load "temp.lisp")
T
* (hdf5test:test "test2.h5")
dim: 5
dataspace-maxdim: 18446744073709551615
memspace-maxdim: 5
dataspace: 67108866
dataset: 83886080
0
结果文件:
% h5dump test.h5
HDF5 "test.h5" {
GROUP "/" {
DATASET "dataset" {
DATATYPE H5T_STD_I32LE
DATASPACE SIMPLE { ( 5 ) / ( H5S_UNLIMITED ) }
DATA {
(0): 0, 1, 4, 9, 16
}
}
}
}
% h5dump test2.h5
HDF5 "test2.h5" {
GROUP "/" {
DATASET "dataset" {
DATATYPE H5T_STD_I32LE
DATASPACE SIMPLE { ( 5 ) / ( H5S_UNLIMITED ) }
DATA {
(0): 0, 1, 4, 9, 16
}
}
}
}
“跑步”是什么意思?如何编译和运行SLIME/SBCL和SBCL下的代码?在SLIME+SBCL中,我使用(load…)函数直接在SLIME REPL中加载,或者使用C-C-l emacs快捷方式将文件加载到列表图像中。在justsbcl下,我使用(load…)函数或使用--load选项运行SBCL。要运行我只需在REPL.BTW中执行(hdf5test:test“test.h5”),此代码确实需要安装hdf5c库才能运行。我没有被放入调试器,但结果确实不同。在SLIME+SBCL或CLISP中,生成的文件应该是有意义的数据。但是,仅使用SBCL时,数据文件不正确,没有任何有意义的数据。因此,代码的处理方式似乎有所不同;SLIME对环境有什么作用吗?我最近遇到了一个类似的情况,我(忘了我)在SLIME中使用一个保存的核心文件调用SBCL,该文件初始化了我使用的一些库,然后以与shell不同的方式加载这些库(不同的初始化调用)。您是否可能在
低级lisp
或类似版本中将参数传递给SBCL?刚刚检查了您的解决方案,它也在我的机器上工作!我不知道为什么SBCL而不是SLIME+SBCL或CLISP失败,但我可以确认dim变量是:int实际上是错误的,所以不同的实现对错误代码的处理可能并不重要。