天天看點

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++ >> 預編譯頭 >> 建立、使用預編譯頭(不使用預編譯頭)