天天看点

SQLite第二课 下载编译

文件说明

下载源码包两个:

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++ >> 预编译头 >> 创建、使用预编译头(不使用预编译头)