CPP檔案和C檔案混編和將sqlite3加入自己的c++工程
阿新 • • 發佈:2018-11-16
今天嘗試將使用sqlite3資料庫,直接使用sqlite3的原始碼,得到sqlite3.c和sqlite3.h。
我想將他們加入到我的cpp工程裡面
所以我新建了一個mysqlite3.cpp檔案,在裡面呼叫了sqlite3的函式。
下面來說明我遇到的問題及解決方法
一共有兩種編譯方法,一種使用gcc/g++編譯,一種使用cmake編譯,下面就來說明這兩種方法
工程原始碼在最後面。
第一種:使用gcc/g++編譯
1.g++ mysqlite.cpp sqlite3.c -o a.out
直接報了一大堆invalid use of incomplete type "XXX"的錯誤。
解決方法就是.cpp檔案和.c檔案要分開編譯,分別用gcc和g++編譯成.o,再用g++將多個.o連線起來
2.gcc -c sqlite3.c -o sqlite3.o
也是報了一堆,對‘pthread_create’未定義的引用,表示找不到pthread_create等函式,應該是沒有連線執行緒庫檔案
解決辦法,加上 -lpthread
3.gcc -c sqlite3.c -o sqlite3.o -lpthread
又報了一堆對‘dlopen’未定義的引用,表示找不到dl庫
解決辦法,加上-ldl
4.gcc -c sqlite3.c -o sqlite3.o -lpthread -ldl
成功生成sqlite3.o
5.g++ -c mysqlite.cpp -o mysqlite.o
一次成功,生成mysqlite3.o
6.g++ mysqlite.o sqlite3.o -o a.out
報了pthread和dl的未定義的引用,加上
7.g++ mysqlite.o sqlite3.o -o a.out -lpthread -ldl
成功生成a.out
8.執行a.out
OKOKOK
第二種:使用cmake編譯
cmake的安裝可看別的部落格
!!!cmake很好用,真的很好用,沒學過的一定要學
1.同樣是找不到pthread和dl
CMakeLists.txt原始碼如下
cmake_minimum_required(VERSION 2.8)
aux_source_directory(. SRC_LIST)
add_executable(apple ${SRC_LIST})
新增pthread庫和dl庫
2.成功
CMakeLists.txt原始碼如下
cmake_minimum_required(VERSION 2.8)
link_libraries(pthread)
link_libraries(dl)
aux_source_directory(. SRC_LIST)
add_executable(apple ${SRC_LIST})
成功生成apple可執行檔案
下面附上工程原始碼
sqlite3.c和sqlite3.h就不貼了,就貼我自己寫的mysqlite3.cpp
單個函式
1.開啟資料庫檔案
int DbOpen(const char * addr) //開啟資料庫,不存在,就建立一個同名的
{
int ret = 0;
ret = sqlite3_open(addr,&database);
printf("open : %d\n", ret);
if(ret != SQLITE_OK){
return -1;
}
return 0;
}
2.建立資料表
int DbCreateTbl()
{
int rc = sqlite3_exec(database, "create table tblTest(id int, name varchar(128));", 0, 0, &errMsg);
//加上容錯
printf("errMSG = %s\n",errMsg);
return 0;
}
3.插入資料
int DbInsert() //插入資料
{
int rc = sqlite3_exec(database, "insert into tblTest values(1,'隨便');", 0, 0, &errMsg);
//加上容錯
return 0;
}
4.利用回撥函式查詢資料
//每查到一條記錄,就執行該回調函式
//para是sqlite3裡面傳入的值,現在我們傳入了0
//nCount是這一條記錄有幾個欄位
//pValue查詢到的資料都在這裡
//pName表示這個欄位的欄位名稱
//沒找到一個記錄,會呼叫一次該函式,別忘記最後的return。
int callback(void*para , int nCount, char** pValue, char** pName)
{
for(int i=0;i<nCount;i++){
printf("nCount = %d,pValue = %s,pName = %s\n", nCount,pValue[i], pName[i]);
}
return 0;
}
int DbSearch_1() //使用回撥函式查詢
{
int rc = sqlite3_exec(database, "select * from tblTest where id = 3;", callback, 0, &errMsg);
//加容錯
return 0;
}
5.利用sqlite3_get_table查詢資料
int DbSearch_2() //利用sqlite3_get_table查詢資料
{
char** pResult;
int nRow;
int nCol;
int rc = sqlite3_get_table(database,"select * from tblTest where id = 3;",&pResult,&nRow,&nCol,&errMsg);
if (rc != SQLITE_OK)
{
sqlite3_free(errMsg);
sqlite3_close(database);
return -1;
}
printf("nRow = %d,nCol = %d\n",nRow, nCol);
//for(int i=0;i<(nRow+1) * nCol;i++) 得到表中查詢結果的所有資料
//for(int i=col;i<(nRow+1) * nCol;i++) 得到查詢結果去除表頭所有資料
//for(int i=nCol;i<(nRow+1) * nCol;i=i+nCol) 去除表頭得到結果集的第一列結果
//for(int i=nCol+1;i<(nRow+1) * nCol;i=i+nCol) 去除表頭得到結果集的第二列結果
for(int i=nCol;i<(nRow+1) * nCol;i=i+nCol)
{
printf("id = %s,",pResult[i]);
printf("name = %s\n",pResult[i+1]);
}
return 0;
}
6.利用sqlite3_prepare、sqlite3_step查詢資料
int DbSearch_3() //利用sqlite3_prepare、sqlite3_step查詢資料
{
sqlite3_stmt *stmt = NULL;
const char *zTail;
if(sqlite3_prepare_v2(database, "select * from tblTest where id = 3;", -1, &stmt, &zTail) == SQLITE_OK)
{
while(sqlite3_step(stmt) == SQLITE_ROW) //不包括列標題
{
int id = sqlite3_column_int(stmt, 0); //表示第一列
const unsigned char *name = sqlite3_column_text(stmt, 1); //表示第二列
printf("id = %d, name = %s\n", id, name);
}
}
sqlite3_finalize(stmt);
return 0;
}
7.關閉資料庫
int DbClose() //關閉資料庫
{
sqlite3_free(errMsg);
sqlite3_close(database);
return 0;
}
總的檔案
#include "sqlite3.h"
#include <stdio.h>
#include <iostream>
#include <string>
#include <vector>
#include <string.h>
#include <cstring>
using namespace std;
int DbOpen(const char * addr); //開啟資料庫檔案,如果沒有同名的,則新建立一個
int DbClose(); //關閉資料庫
int DbCreateTbl(); //在資料庫檔案中建立資料表,如果存在同名的,則不會建立
int DbInsert(); //插入資料
int callback(void*para , int nCount, char** pValue, char** pName); //回撥函式
int DbSearch_1(); //利用回撥函式查詢資料
int DbSearch_2(); //利用sqlite3_get_table查詢資料
int DbSearch_3(); //利用sqlite3_prepare、sqlite3_step查詢資料
sqlite3 *database = NULL;
char * errMsg = NULL;
int main()
{
DbOpen("aaa");
DbCreateTbl();
DbInsert();
DbSearch_1();
printf("--------------------------\n");
DbSearch_2();
printf("--------------------------\n");
DbSearch_3();
printf("--------------------------\n");
DbClose();
return 0;
}
//每查到一條記錄,就執行該回調函式
//para是sqlite3裡面傳入的值,現在我們傳入了0
//nCount是這一條記錄有幾個欄位
//pValue查詢到的資料都在這裡
//pName表示這個欄位的欄位名稱
//沒找到一個記錄,會呼叫一次該函式,別忘記最後的return。
int callback(void*para , int nCount, char** pValue, char** pName)
{
for(int i=0;i<nCount;i++){
printf("nCount = %d,pValue = %s,pName = %s\n", nCount,pValue[i], pName[i]);
}
return 0;
}
int DbSearch_1() //使用回撥函式查詢
{
int rc = sqlite3_exec(database, "select * from tblTest where id = 3;", callback, 0, &errMsg);
//加容錯
return 0;
}
int DbSearch_2() //利用sqlite3_get_table查詢資料
{
char** pResult;
int nRow;
int nCol;
int rc = sqlite3_get_table(database,"select * from tblTest where id = 3;",&pResult,&nRow,&nCol,&errMsg);
if (rc != SQLITE_OK)
{
sqlite3_free(errMsg);
sqlite3_close(database);
return -1;
}
printf("nRow = %d,nCol = %d\n",nRow, nCol);
for(int i=nCol;i<(nRow+1) * nCol;i=i+nCol)
{
printf("id = %s,",pResult[i]);
printf("name = %s\n",pResult[i+1]);
}
return 0;
}
int DbSearch_3() //利用sqlite3_prepare、sqlite3_step查詢資料
{
sqlite3_stmt *stmt = NULL;
const char *zTail;
if(sqlite3_prepare_v2(database, "select * from tblTest where id = 3;", -1, &stmt, &zTail) == SQLITE_OK)
{
while(sqlite3_step(stmt) == SQLITE_ROW) //不包括列標題
{
int id = sqlite3_column_int(stmt, 0); //表示第一列
const unsigned char *name = sqlite3_column_text(stmt, 1); //表示第二列
printf("id = %d, name = %s\n", id, name);
}
}
sqlite3_finalize(stmt);
return 0;
}
int DbInsert() //插入資料
{
int rc = sqlite3_exec(database, "insert into tblTest values(1,'隨便');", 0, 0, &errMsg);
return 0;
}
//建立一張資料表,如果存在同名數據表,則errMSG = table tblTest already exists。繼續執行
int DbCreateTbl()
{
int rc = sqlite3_exec(database, "create table tblTest(id int, name varchar(128));", 0, 0, &errMsg);
printf("errMSG = %s\n",errMsg);
return 0;
}
int DbOpen(const char * addr) //開啟資料庫,不存在,就建立一個同名的
{
int ret = 0;
ret = sqlite3_open(addr,&database);
printf("open : %d\n", ret);
if(ret != SQLITE_OK){
return -1;
}
return 0;
}
int DbClose() //關閉資料庫
{
sqlite3_free(errMsg);
sqlite3_close(database);
return 0;
}