如何强制CFFI定义的CL-SQLITE使用指定版本的SQLite3共享库?
解决CL-SQLITE加载MSYS UCRT64下SQLite DLL的问题
核心思路
CL-SQLITE依赖CFFI加载名为sqlite3的外部库,我们可以在CL-SQLITE加载前重新定义这个CFFI外部库的规则,指定MSYS UCRT64下的具体DLL路径,无需修改CL-SQLITE源码或复制重命名DLL。
方案1:手动预定义CFFI库(快速验证)
在执行ql:quickload :cl-sqlite前,先加载CFFI并重新定义sqlite3库的加载规则:
;; 先加载CFFI (ql:quickload :cffi) ;; 重新定义sqlite3外部库,替换为你的MSYS UCRT64下的DLL路径 (cffi:define-foreign-library sqlite3 (:windows "C:/msys64/ucrt64/bin/libsqlite3.dll") ; 替换为实际路径 (t (:default "sqlite3"))) ; 其他平台沿用默认规则 ;; 启用这个自定义库定义 (cffi:use-foreign-library sqlite3) ;; 现在可以正常加载CL-SQLITE了 (ql:quickload :cl-sqlite)
原理:CFFI允许重复定义同名外部库,后定义的会覆盖之前的。CL-SQLITE加载时会使用我们提前定义的规则,直接指向MSYS的DLL。
方案2:集成到ASDF项目配置(长期维护)
如果是基于ASDF的项目,可以在项目系统文件中添加前置操作,自动处理库定义:
(defsystem :your-project-name :depends-on (:cl-sqlite) :defsystem-depends-on (:cffi) ;; 在加载项目前先处理SQLite库定义 :perform (load-op :before (op system) (ql:quickload :cffi) (cffi:define-foreign-library sqlite3 (:windows "C:/msys64/ucrt64/bin/libsqlite3.dll") (t (:default "sqlite3"))) (cffi:use-foreign-library sqlite3)))
这样每次加载你的项目时,ASDF会自动先设置好SQLite的库路径,再加载CL-SQLITE。
方案3:结合DEPLOY工具打包
如果你需要用DEPLOY打包应用,需要先确保CL-SQLITE能正常加载,再配置DEPLOY的库规则:
;; 先预定义CFFI库,确保CL-SQLITE能加载 (ql:quickload :cffi) (cffi:define-foreign-library sqlite3 (:windows "C:/msys64/ucrt64/bin/libsqlite3.dll") (t (:default "sqlite3"))) (cffi:use-foreign-library sqlite3) ;; 加载依赖 (ql:quickload :cl-sqlite) (ql:quickload :deploy) ;; 告诉DEPLOY要打包这个DLL (deploy:define-library sqlite3 :path "C:/msys64/ucrt64/bin/libsqlite3.dll" :dont-copy nil) ; 设置为nil会将DLL复制到部署目录,按需调整 ;; 执行打包 (deploy:deploy :your-project-name)
解决你之前的问题:DEPLOY的define-library需要依赖CFFI库已成功加载,所以必须先通过预定义让CL-SQLITE能正常启动,再配置DEPLOY。
内容的提问来源于stack exchange,提问作者MonadMania
相关产品推荐
相关产品推荐

