如何强制 CFFI 定义的外部库使用特定版本的共享库?

问题描述 投票:0回答:1

我正在使用 CL-SQLITE,它是使用 CFFI(通用外部函数接口)编写的 SQLite3 的 Common Lisp 包装器。我首选的 C 运行时是随 MSYS 一起分发的 UCRT64。不幸的是,MSYS 使用自己的 DLL 命名约定,因此 CFFI 搜索的默认文件名将找不到。我想告诉 CL-SQLITE 加载我的特殊 DLL,而不是搜索默认选项。我不想修改 CL-SQLITE 代码,因为这会造成维护负担。我也不想做“简单的事情”并将 DLL 复制到我的项目目录,并根据需要重命名;当我将其他共享库合并到我的项目中时,这些复制操作将成为问题。

我还使用 ASDF 和 DEPLOY,因此如果这些工具提供了解决方案,那么我就可以使用它。

我尝试使用DEPLOY的define-library指向我的本地DLL,但是define-library依赖于成功加载CFFI系统。 CL-SQLITE 不会成功 QL:QUICKLOAD,因为它正在查找的 DLL 的名称与我的名称不同。

我还尝试向 cffi 添加一个目录:*foreign-library-directories*。这并没有解决问题,因为文件名不同;目录名称不是问题。

common-lisp asdf cffi
1个回答
0
投票

我遇到了同样的问题,必须做两件事才能解决。

在我安装的 MSYS2 中,

libsqlite3
库被命名为
libsqlite3-0.dll
。从 UCRT64 终端窗口,我在该目录中创建了指向
libsqlite3.dll
的软链接:

$ cd /c/msys64/ucrt64/bin/
$ ln -s libsqlite3-0.dll libsqlite3.dll

然后我必须添加一个搜索路径,以便 CLSQL 可以找到库代码。您可以在使用 Quicklisp 加载 CLSQL 后执行

CL-USER> (clsql:push-library-path #P"C:/msys64/ucrt64/bin/")
,也可以创建一个初始化文件。这没有很好的记录:CLSQL 文档中有一个简要提及,并且可以通过搜索 clsql-init 的CLSQL 更改日志来收集更多信息。看来您可以在 *nix 系统上的 clsql-init.lisp
 下、Windows 系统上的 
/etc/
 下或任一类型系统上的 
c:\etc\clsql-init.lisp
 下添加名为 
~/.clsql-init.lisp
 的文件。请注意,最后一个变体是一个点文件。

我将

.clsql-init.lisp

 添加到我的主目录中:

;;; Add library path for sqlite3. (clsql:push-library-path #P"C:/msys64/ucrt64/bin/")
进行这两项更改后,一切似乎都按预期进行。

© www.soinside.com 2019 - 2024. All rights reserved.