不确定这是否是错误,但错误来自sqlite3.h
sqlite 包的包含。
查看文件显示了这一点
/*
** CAPI3REF: Name Of The Folder Holding Temporary Files {H10310} <S20000>
**
** If this global variable is made to point to a string which is
** the name of a folder (a.k.a. directory), then all temporary files
** created by SQLite will be placed in that directory. If this variable
** is a NULL pointer, then SQLite performs a search for an appropriate
** temporary file directory.
**
** It is not safe to modify this variable once a [database connection]
** has been opened. It is intended that this variable be set once
** as part of process initialization and before any SQLite interface
** routines have been call and remain unchanged thereafter.
*/
SQLITE_EXTERN char *sqlite3_temp_directory;
所以它被声明为外部。如此简单的测试:
module Main where
import Database.SQLite
main
= do hwd <- openConnection "test"
closeConnection hwd
putStrLn "done"
这会在链接过程中按预期崩溃,并出现上述错误。所以我创建了一个小的 C 测试文件foo.c
#include "sqlite-0.5.2.2\\include\\sqlite3-local.h"
char* sqlite3_temp_directory = "C:\\test2";
所以我定义了一个 temp_directory,然后在编译 haskell 源代码的过程中传递 c 文件
$ ghc test.hs foo.c
[1 of 1] Compiling Main ( test.hs, test.o )
Linking test.exe ...
然后运行它也会返回预期的结果
$ ./test
done
因此,您似乎只需要为 sqlite3_temp_directory 提供一个值,如果将其设置为 NULL 指针,将使用 SQLLITE 手册中定义的 TMP/TEMP 等变量。
编辑,跟进为什么它可以在 Linux 上运行,但不能在 Windows 上运行
在 sqlite 包中,文件夹 sqlite3.6 下有一个文件 sqlite3.c。这为 sqlite 包提供了一堆默认值。
在 linux 上定义 OS_UNIX 时,在 linux 上使用 OS_WIN 下的定义。我们感兴趣的函数是设置临时目录的函数。对于 unix 这将是unixGetTempname
和对于 windows winGetTempname
。
如果您查看这两个函数的实现,对于 unix 来说,它有目录列表,它将尝试
static const char *azDirs[] = {
0,
"/var/tmp",
"/usr/tmp",
"/tmp",
".",
};
它会尝试按顺序访问它们,并且它可以写入的文件用于在其中生成一个临时文件夹。
但是,对于 Windows,第一行之一是:
if( sqlite3_temp_directory ){
sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
}else if( isNT() ){
所以对于windowssqlite3_temp_directory
实际上是用的。这就是为什么如果找不到它就无法编译的原因。