sqlite純go語言的簡單介紹

go語言適合做什么?

Go語言。他主要是在一些網(wǎng)頁版的服務(wù)器中用于系統(tǒng)編程的一種語言。他是谷歌開發(fā)的一種編程語言。在一定程度上,谷歌有一定的壟斷作用。不能隨隨便便的在語言當(dāng)中添加其他的語言成分。

公司主營業(yè)務(wù):網(wǎng)站設(shè)計制作、成都網(wǎng)站設(shè)計、移動網(wǎng)站開發(fā)等業(yè)務(wù)。幫助企業(yè)客戶真正實現(xiàn)互聯(lián)網(wǎng)宣傳,提高企業(yè)的競爭能力。創(chuàng)新互聯(lián)公司是一支青春激揚、勤奮敬業(yè)、活力青春激揚、勤奮敬業(yè)、活力澎湃、和諧高效的團隊。公司秉承以“開放、自由、嚴謹、自律”為核心的企業(yè)文化,感謝他們對我們的高要求,感謝他們從不同領(lǐng)域給我們帶來的挑戰(zhàn),讓我們激情的團隊有機會用頭腦與智慧不斷的給客戶帶來驚喜。創(chuàng)新互聯(lián)公司推出元氏免費做網(wǎng)站回饋大家。

如何編譯SQLite-How To Compile SQLite

SQLite是ANSI-C的源代碼。在使用之前必須要編譯成機器碼。這篇文章是用于各種編譯SQLite方法的指南。

這篇文章不包含編譯SQLite的每個步驟的反饋,那樣可能會困難因為每種開發(fā)場景都不同。所以這篇文章描述和闡述了編譯Sqlite的原則。典型的編譯命令已經(jīng)作為例子提供了,以期望應(yīng)用開發(fā)者能夠使用這些例子作為完成他們自己定制的編譯過程的的一個指南。換句話說,這篇文章提供了想法和見解,而不是交鑰匙的解決方法。

融合VS單獨源文件

Sqlite是由超過一百個c源碼文件以及眾多的目錄下的腳本構(gòu)建的。Sqlite的實現(xiàn)是純粹的ANSI-C,但是許多C語言源代碼文件是由輔助的C程序生成或者轉(zhuǎn)換來的,并且AWK,SED和TCL腳本會融合到完成的sqlite庫中。對Sqlite構(gòu)建需要的C程序和轉(zhuǎn)換和創(chuàng)建C語言源碼是一個復(fù)雜的過程。

為了簡化這些,sqlite也通過一個預(yù)打包的合并后的源碼文件:sqlite3.c。這個合并文件是一個ANSI-C源碼實現(xiàn)整個SQLite庫的唯一文件。合并后的文件更容易處理。所有的東西都包含在這一個文件里,所以很容易進入一個更大的C或者C++程序的源碼樹。所有的代碼生成和轉(zhuǎn)換步驟都已經(jīng)實現(xiàn)了,因此沒有輔助的C程序需要去配置和變異,也沒有腳本需要去運行。并且,因此所有哭都包含在一個翻譯單元,編譯器可以做更多高級的優(yōu)化從而提升5%到10%的性能。因為這些原因,融合后的源碼文件sqlite3.c對所有程序來講都是值得推薦的。

推薦所有的應(yīng)用程序使用融合文件。

直接從單獨的源碼文件中構(gòu)建sqlite當(dāng)然可以,但是并不推薦。對一些特殊的應(yīng)用程序,可能需要修改構(gòu)建程序去處理使用那些從網(wǎng)站上下載的預(yù)構(gòu)建的源碼文件不能完成的情況。對于這些情況,推薦構(gòu)建和使用一個定制過的合并文件。換句話說,即使一個工程需要以單獨的源碼文件構(gòu)建sqlite,仍然推薦使用一個融合后的源碼文件作為一個中間步驟。

編譯命令行接口(CLI)

構(gòu)建命令行接口需要三個源碼文件:

sqlite3.c:Sqlite融合的源碼文件

sqlite3.h:匹配sqlite3.c以及定義sqlite的c語言接口的頭文件

shell.c:命令行接口程序本身。這個c源碼文件包含一個main()的例程和每輪循環(huán)的用戶輸入的提示符并將輸入傳給sqlite數(shù)據(jù)庫引擎用于處理。

所有的上述源碼的三個文件都被包含在下載頁面的amalgamation tarball中。

為了構(gòu)建CLI,簡單的將這三個文件放置在相同的目錄下然后一起編譯他們。用MSVC:

cl shell.c sqlite3.c -Fesqlite3.exe

在unix系統(tǒng)上(或者在windows上用cygwin或者mingw+msys)典型的命令會有些像這樣:

gcc shell.c sqlite3.c -lpthread -ldl

為了SQLite線程安全,需要pthreads庫。但是因為CLI是一個單線程的,我們可以指示SQLite構(gòu)建一個非線程安全的庫并因此護綠pthreads庫:

gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl

-ldl庫是在支持動態(tài)裝載時需要,例如sqlite3_load_extension() 接口和load_extension()

SQL function。如果這些特性都不要求,那么我們也可以使用SQLITE_OMIT_LOAD_EXTENSION編譯時間選項忽略他們。

gcc -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c

有人可能想要提供其他的編譯時間選項(compile-time options),例如SQLITE_ENABLE_FTS3去全文本搜索或者SQLITE_ENABLE_RTREE用于R*樹搜索引擎擴展。而有人將正常指定一些編譯優(yōu)化開關(guān)。(預(yù)編譯的CLI可以從選擇sqlite網(wǎng)站上使用“-Os”下載下來)有無數(shù)種可能的變數(shù)在這里。

關(guān)鍵點在這里:構(gòu)建CLI需要編譯一起兩個C語言文件。shell.c文件包含入口的定義和用戶輸入的loop,而sqlite融合文件sqlite3.c包含完整的sqlite庫的實現(xiàn)。

編譯TCL接口

sqlite的tcl接口是一個小的模塊被添加到一般的融合文件中。結(jié)果是一個新的融合后的源碼文件,稱之為“tclsqlite3.c”。這個源碼文件是生成一個可以使用TCL

load命令去加載到一個標(biāo)準(zhǔn)的tclsh或者wish中,或者隨著sqlite構(gòu)建成功生成一個單獨唯一的tclsh的共享庫所需要的。一個tcl的融合的副本被包含在下載頁的TEA

tarball中作為一個文件。

為了生成一個linux上的sqlite的TCL-loadable庫,下面的命令需要滿足:

gcc -o libtclsqlite3.so -shared tclsqlite3.c -lpthread -ldl -ltcl

不幸的是構(gòu)建Mac OS X 和 Windows的共享庫并不是如此簡單。對于這些平臺最好使用包含在TEA tarball中的configure腳本和makefile.

為了生成一個單獨的tclsh,可以用于sqlite靜態(tài)鏈接,使用如下的編譯器調(diào)用:

gcc -DTCLSH=1 tclsqlite3.c -ltcl -lpthread -ldl -lz -lm

這里的技巧是-DTCLSH=1選項。sqlite的TCL接口模塊包含一個main的過程,用于初始化一個TCL解釋器并在以-DTCLSH=1編譯后進入到一個命令行l(wèi)oop。上述命令可以工作在Linux和Mac

OS X,雖然有時可能需要依賴于平臺調(diào)整庫選項以及編譯的TCL的哪一個版本。

構(gòu)建融合文件

下載頁提供的sqlite融合文件的版本對大多數(shù)用戶來說是足夠的。然而,一些工程可能想要或者需要構(gòu)建他們自己的融合文件。一個常見的構(gòu)建一個定制的融合文件的理由是為了使用特定的compile-time options來定制sqlite庫?;叵雜qlite融合文件中包含了許多C代碼由輔助程序和腳本生成。許多的編譯時間選項影響這一成圣代碼而且必須在融合文件組裝前提供給代碼生成器。這一系列必須傳給代碼生成器的編譯時間相關(guān)的選項會使得sqlite的發(fā)布版本各不相同,但是在寫這邊文章的時候,代碼生成器需要知道的這組選項包括:

SQLITE_ENABLE_UPDATE_DELETE_LIMIT

SQLITE_OMIT_ALTERTABLE

SQLITE_OMIT_ANALYZE

SQLITE_OMIT_ATTACH

SQLITE_OMIT_AUTOINCREMENT

SQLITE_OMIT_CAST

SQLITE_OMIT_COMPOUND_SELECT

SQLITE_OMIT_EXPLAIN

SQLITE_OMIT_FOREIGN_KEY

SQLITE_OMIT_PRAGMA

SQLITE_OMIT_REINDEX

SQLITE_OMIT_SUBQUERY

SQLITE_OMIT_TEMPDB

SQLITE_OMIT_TRIGGER

SQLITE_OMIT_VACUUM

SQLITE_OMIT_VIEW

SQLITE_OMIT_VIRTUALTABLE

為了構(gòu)建一個定制的融合文件,先下載原始的獨立源碼文件到一個unix或者類unix開發(fā)平臺。確定獲取的原始源碼文件不是“預(yù)編譯過的源文件”。任何人都可以通過到下載頁或者直接從configuration management system.獲取完整的一套原始源碼文件。

假設(shè)sqlite源碼樹被存在一個名為“sqlite”的目錄下。計劃構(gòu)建一個平行目錄下的名為“bld”的融合文件。首先通過運行sqlite源碼樹種的configure腳本運行或者通過制作一份源碼樹頂層的的makfile模板的一份,來構(gòu)建一個合適的makefile.然后手動編輯這個Makfile去包含需要的編譯時間相關(guān)的選項。最終運行:

make sqlite3.c

在windows上使用MSVC:

nmake /f Makefile.msc sqlite3.c

sqlite3.c的make

target會自動構(gòu)造一般的“sqlite3.c”合并的源碼文件,以及它的頭文件“sqlite3.h”,和包含TCL接口的融合源碼文件“tclsqlite3.c”。之后,需要的文件可以被拷貝到文件目錄下然后根據(jù)上述勾勒的過程編譯。

構(gòu)建一個windows的動態(tài)鏈接庫DLL

為了在windows構(gòu)建一個sqlite的dll使用,首先獲取對應(yīng)的融合過的源碼文件,sqlit3.c和sqlite.h。這些可以從SQLite website上下載或者和上述告知的一樣去定制生成。

使用工作目錄下的源碼文件,一個dll可以在msvc中使用如下命令生成:

cl sqlite3.c -link -dll -out:sqlite3.dll

上述命令需要運行在msvc的MSVC Native Tools Command

Prompt.如何你已經(jīng)在機器上安裝了msvc,你可能有多個版本的這種命令提示符,針對于x86和x64的自帶構(gòu)建的,或者交叉編譯到ARM的。依賴要求的DLL去使用對應(yīng)合適的命令提示符工具。

如果使用MinGW編譯器,命令是這樣的:

gcc -shared sqlite3.c -o sqlite3.dll

注意MinGW只生成32位的dll。另有一個分開的MinGW64工程可以用來生成64位的dll??梢酝茢嗥涿钚姓Z法是類似的。需要注意的是最近的MSVC的版本生成的DLLs可能不能工作到WinXP或者更早版本的windows上。因此為了最大限度的兼容你的生成的dll,推薦MinGW。一個好的經(jīng)驗法則是使用MinGW去生成32位的dlls,使用msvc去生成64位的dlls。

如何在golang 中調(diào)用c的靜態(tài)庫或者動態(tài)庫

Cgo 使得Go程序能夠調(diào)用C代碼. cgo讀入一個用特別的格式寫的Go語言源文件, 輸出Go和C程序, 使得C程序能打包到Go語言的程序包中.

舉例說明一下. 下面是一個Go語言包, 包含了兩個函數(shù) -- Random 和 Seed -- 是C語言庫中random和srandom函數(shù)的馬甲.

package rand

/*

#include stdlib.h

*/ import "C" func Random() int { return int(C.random()) } func Seed(i int) { C.srandom(C.uint(i)) }

我們來看一下這里都有什么內(nèi)容. 開始是一個包的導(dǎo)入語句.

rand包導(dǎo)入了"C"包, 但你會發(fā)現(xiàn)在Go的標(biāo)準(zhǔn)庫里沒有這個包. 那是因為C是一個"偽包", 一個為cgo引入的特殊的包名, 它是C命名空間的一個引用.

rand 包包含4個到C包的引用: 調(diào)用 C.random和C.srandom, 類型轉(zhuǎn)換 C.uint(i)還有引用語句.

Random函數(shù)調(diào)用libc中的random函數(shù), 然后回返結(jié)果. 在C中, random返回一個C類型的長整形值, cgo把它輪換為C.long. 這個值必需轉(zhuǎn)換成Go的類型, 才能在Go程序中使用. 使用一個常見的Go類型轉(zhuǎn)換:

func Random() int { return int(C.random()) }

這是一個等價的函數(shù), 使用了一個臨時變量來進行類型轉(zhuǎn)換:

func Random() int { var r C.long = C.random() return int(r) }

Seed函數(shù)則相反. 它接受一個Go語言的int類型, 轉(zhuǎn)換成C語言的unsigned int類型, 然后傳遞給C的srandom函數(shù).

func Seed(i int) { C.srandom(C.uint(i)) }

需要注意的是, cgo中的unsigned int類型寫為C.uint; cgo的文檔中有完整的類型列表.

這個例子中還有一個細節(jié)我們沒有說到, 那就是導(dǎo)入語句上面的注釋.

/*

#include stdlib.h

*/ import "C"

Cgo可以識別這個注釋, 并在編譯C語言程序的時候?qū)⑺?dāng)作一個頭文件來處理. 在這個例子中, 它只是一個include語句, 然而其實它可以是使用有效的C語言代碼. 這個注釋必需緊靠在import "C"這個語句的上面, 不能有空行, 就像是文檔注釋一樣.

Strings and things

與Go語言不同, C語言中沒有顯式的字符串類型. 字符串在C語言中是一個以0結(jié)尾的字符數(shù)組.

Go和C語言中的字符串轉(zhuǎn)換是通過C.CString, C.GoString,和C.GoStringN這些函數(shù)進行的. 這些轉(zhuǎn)換將得到字符串類型的一個副本.

下一個例子是實現(xiàn)一個Print函數(shù), 它使用C標(biāo)準(zhǔn)庫中的fputs函數(shù)把一個字符串寫到標(biāo)準(zhǔn)輸出上:

package print // #include stdio.h // #include stdlib.h import "C" import "unsafe" func Print(s string) { cs := C.CString(s) C.fputs(cs, (*C.FILE)(C.stdout)) C.free(unsafe.Pointer(cs)) }

在C程序中進行的內(nèi)存分配是不能被Go語言的內(nèi)存管理器感知的. 當(dāng)你使用C.CString創(chuàng)建一個C字符串時(或者其它類型的C語言內(nèi)存分配), 你必需記得在使用完后用C.free來釋放它.

調(diào)用C.CString將返回一個指向字符數(shù)組開始處的指錯, 所以在函數(shù)退出前我們把它轉(zhuǎn)換成一個unsafe.Pointer(Go中與C的void 等價的東西), 使用C.free來釋放分配的內(nèi)存. 一個慣用法是在分配內(nèi)存后緊跟一個defer(特別是當(dāng)這段代碼比較復(fù)雜的時候), 這樣我們就有了下面這個Print函數(shù):

func Print(s string) { cs := C.CString(s) defer C.free(unsafe.Pointer(cs)) C.fputs(cs, (*C.FILE)(C.stdout)) }

構(gòu)建 cgo 包

如果你使用goinstall, 構(gòu)建cgo包就比較容易了, 只要調(diào)用像平常一樣使用goinstall命令, 它就能自動識別這個特殊的import "C", 然后自動使用cgo來編譯這些文件.

如果你想使用Go的Makefiles來構(gòu)建, 那在CGOFILES變量中列出那些要用cgo處理的文件, 就像GOFILES變量包含一般的Go源文件一樣.

rand包的Makefile可以寫成下面這樣:

include $(GOROOT)/src/Make.inc

TARG=goblog/rand

CGOFILES=\ rand.go\ include $(GOROOT)/src/Make.pkg

然后輸入gomake開始構(gòu)建.

更多 cgo 的資源

cgo的文檔中包含了關(guān)于C偽包的更多詳細的說明, 以及構(gòu)建過程. Go代碼樹中的cgo的例子給出了更多更高級的用法.

一個簡單而又符合Go慣用法的基于cgo的包是Russ Cox寫的gosqlite. 而Go語言的網(wǎng)站上也列出了更多的的cgo包.

最后, 如果你對于cgo的內(nèi)部是怎么運作這個事情感到好奇的話, 去看看運行時包的cgocall.c文件的注釋吧.

golang操作sqlite3

MacBook Linux Windows等系統(tǒng)安裝sqlite3

MacBook Linux 樹莓派raspberrypi安裝Golang環(huán)境

文章名稱:sqlite純go語言的簡單介紹
文章位置:http://muchs.cn/article30/hgeipo.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站維護、軟件開發(fā)、外貿(mào)建站、網(wǎng)站內(nèi)鏈品牌網(wǎng)站制作、定制網(wǎng)站

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

手機網(wǎng)站建設(shè)