文件说明
下载源码包两个:
sqlite-dll-win32-x86-3081101.zip,里面提供了导出sqlite3的函数的文件sqlite3.def
主要用于生成LIB文件,确定链接使用
sqlite-preprocessed-3081101.zip,提供了源码文件,但是删除shell.c和tclsqlite3.c文件
shell.c:提供了main函数入口,可生成sqlite.exe的可执行程序,生成的控制台操作SQLite数据库
tclsqlite.c:提供了在Linux系统下,进行测试SQLite的TCL脚本
这两个文件对于编译环境是windows,只是将SQLite编译进程序中都不需要,添加源代码的时候,需要进行剔除。
sqlite3.h:提供了对外使用的所有接口
sqlite3ext.h:该文件暂时不了解
** This header file defines the SQLiteinterface for use by
** shared libraries that want to beimported as extensions into
** an SQLite instance. Shared libraries that intend to be loaded
** as extensions by SQLite should #includethis file instead of
** sqlite3.h.
2 编译选项说明
必选编译选项:
SQLITE_CORE
FTS1有一个设计的缺陷,会导致数据库错误(databasecorruption).强烈推荐废弃该模块,改用fts3或者更高的模块。如果你相信fts1的使用是安全的,可以通过添加DSQLITE_ENABLE_BROKEN_FTS1=1到编译选项。
FTS1模块将会作为一个扩展模块而被编译(当SQLITE_CORE没有被定义的情况下)。
另外如果SQLITE_ENABLE_FTS1被定义,FTS1也会被编译进SQLite内核。
可选编译选项:
SQLITE_ENABLE_RTREE
将Rtree模块编译进SQLite内核,本研究针对二维空间的POI进行存储,
所以必须开启Rtree模块,稍后会进行源码剖析。
SQLITE_ENABLE_COLUMN_METADATA
作用:可以调用如下的函数
SQLITE_API const char *SQLITE_STDCALL sqlite3_column_database_name(sqlite3_stmt*,int);
SQLITE_API
const void *SQLITE_STDCALL sqlite3_column_database_name16(sqlite3_stmt*,int);
SQLITE_API const
char *SQLITE_STDCALL sqlite3_column_table_name(sqlite3_stmt*,int);
SQLITE_API const void
*SQLITE_STDCALL sqlite3_column_table_name16(sqlite3_stmt*,int);
SQLITE_API const char
*SQLITE_STDCALL sqlite3_column_origin_name(sqlite3_stmt*,int);
SQLITE_API const void
*SQLITE_STDCALL sqlite3_column_origin_name16(sqlite3_stmt*,int);
这些函数主要是获取数据库的库名,表名,列名
调用条件:必须在[sqlite3_step()]之后,[sqlite3_finalize()]之前调用。
1.新建win32控制台程序,名称sqlite3
2.选择生成DLL
3.解压压缩包,将sqlite-preprocessed-3081101的文件复制到工程文件夹下(除了shell.c以及tclsqlite.c)。
4.通过添加存在文件,将源码添加到编译项目中
5设置模块定义文件sqlite3.def,否则生成的dll没有对应的lib
指定函数的导出文件:sqlite3.defs
属性>>链接器>>输入>>模块定义文件(sqlite3.def),请注意这种情况下,sqlite3.def文件和编译环境平级。
6.添加预定义选项SQLITE_CORE,SQLITE_ENABLE_COLUMN_METADATA、SQLITE_ENABLE_RTREE,这是sqlite3的宏定义。
属性>>C/C++>>预处理器>>预处理定义>>
SQLITE_CORE
SQLITE_ENABLE_COLUMN_METADATA
SQLITE_ENABLE_RTREE
编译出错提示:
1>sqlite3.def : error LNK2001: 无法解析的外部符号sqlite3_column_database_name
1>sqlite3.def :error LNK2001: 无法解析的外部符号sqlite3_column_database_name16
1>sqlite3.def :error LNK2001: 无法解析的外部符号sqlite3_column_origin_name
1>sqlite3.def :error LNK2001: 无法解析的外部符号sqlite3_column_origin_name16
1>sqlite3.def :error LNK2001: 无法解析的外部符号sqlite3_column_table_name
1>sqlite3.def :error LNK2001: 无法解析的外部符号sqlite3_column_table_name16
1>sqlite3.def :error LNK2001: 无法解析的外部符号sqlite3_rtree_geometry_callback
1>sqlite3.def :error LNK2001: 无法解析的外部符号sqlite3_rtree_query_callback
前面6个函数,必须定义了SQLITE_ENABLE_COLUMN_METADATA才能够将函数导出,一般情况下,这些函数,我们可以直接在sqlite3.def文件中删除,不导出
后面2个函数,必须定义了SQLITE_ENABLE_RTREE才能够将函数导出,如果我们不适用R树的空间搜索功能,这些函数,我们可以直接在sqlite3.def文件中删除,不导出
7.按F7生成相应的dll和lib。
编译说明
1)fts2 has a designflaw and has been deprecated
2)fts1 has a designflaw and has been deprecated
解决方案:
解析:FTS1和FTS2都有设计的缺陷,现在已经被废弃,目前已经提供了FTS3或者FTS4,这些作为全文搜索的模块,弥补了以前的FTS1的不足。如果确定不会使用到全文搜索,可以直接使用SQLITE_CORE,禁用。将SQLITE_CORE添加到编译选项。
VS 的基本设置:属性>>C/C++>>预处理器》》预处理定义
3)Cannot open includefile: 'unicode/utypes.h': No such file or directory
该问题主要是调用了FTS1或者FTS2引起的,通过禁用FTS1和FTS2顺利编译通过。
FTS1有一个设计的缺陷,会导致数据库错误(databasecorruption).强烈推荐废弃该模块,改用fts3或者更高的模块。如果你相信fts1的使用是安全的,可以通过添加DSQLITE_ENABLE_BROKEN_FTS1=1到编译选项。
FTS1模块将会作为一个扩展模块而被编译(当SQLITE_CORE没有被定义的情况下)。
另外如果SQLITE_ENABLE_FTS1被定义,FTS1也会被编译进SQLite内核。
4)Error: no module:rtree
默认情况下sqlite3.exe的控制台程序是没有携带Rtree模块的,如果需要启用该模块,需要调用预编译定义:SQLITE_ENABLE_RTREE,然后通过shell.c文件的main重新生成程序。
5)控制台程序
建立空的控制台,然后导入sqlite源码,编译出现如下的错误:
error LNK2019: 无法解析的外部符号[email protected],该符号在函数 ___tmainCR...
第一步:在C++/预编译中,添加:SQLITE_ENABLE_RTREE 参数支持rtree
第二步:如果是控制台程序:
1.菜单中选择Project->Properties, 弹出Property Pages窗口
2.在左边栏中依次选择:ConfigurationProperties->C/C++->Preprocessor,然后在右边栏的PreprocessorDefinitions对应的项中删除_WINDOWS, 添加_CONSOLE.
3.在左边栏中依次选择:ConfigurationProperties->Linker->System,然后在右边栏的SubSystem对应的项改为CONSOLE(/SUBSYSTEM:CONSOLE)
6)unexpected end offile while looking for precompiled header. Did you forget to add '#include"stdafx.h"' to your source?
SQLite源码不能够调用预编译处理,因为SQLite的源码是纯C语言,无法获得VC++预编译的好处。
解决:属性 >> C/C++ >> 预编译头 >> 创建、使用预编译头(不使用预编译头)