[英]Embed sqlite database into c++ executable
我認為我的問題與這個問題有關,但是那個問題是關於 png 的,我不知道如何將其轉化為我的情況。
我在以 .db 結尾的文件中使用 sqlite 創建了一個數據庫。 現在我有一個只從這個數據庫中讀取的程序。 有沒有辦法將數據庫文件包含到可執行文件中?
現在,如果我編譯,我必須將可執行文件和文件放在一起。 可以通過將數據庫文件放在絕對路徑中來刪除這種依賴關系,但我也在處理 hpc 集群,所以這不起作用。 我需要一個相對路徑,以便 db 文件與我的 main.cpp 處於同一層次結構,但我希望能夠在不復制 db 文件的情況下復制可執行文件,因此在某種程度上,db 文件已經是可執行文件的一部分。
假設你在你的二進制文件中嵌入了 SQLite 數據庫,你有一個const char *embedded_start
和size_t embedded_length
embedding_length 表示數據庫的開始和長度。
答案取決於您願意投入多少工作:
FILE *db = tmpfile();
fwrite(embedded_start, embedded_length, 1, db);
fflush(db);
std::string path = std::string{"/proc/self/fd/"} + std::to_string(fileno(db));
sqlite3_open_v2(path.c_str(), &dbconn, SQLITE_OPEN_READONLY, nullptr);
/proc/self/fd/X
。有sqlite3_deserialize例程,它從數組中獲取數據庫轉儲並將其“加載”到提供的數據庫連接中。 結合內存數據庫,它可以用來完成你想要的。
// Plain dump of file. Made with xxd -i
unisgned char db_dump[] = {0x53, 0x51, 0x4c, 0x69, 0x74, 0x65, 0x20 ....etc
// Create empty, readonly in-memory db
sqlite3* db = NULL;
sqlite3_open_v2(":memory:", &db, SQLITE_OPEN_READONLY, NULL);
// Reopen db with dump of other one
rc = sqlite3_deserialize(db, "main", db_dump, sizeof(db_dump), sizeof(db_dump),
SQLITE_DESERIALIZE_READONLY);
完整的、可運行的示例(太長,無法在此處發布)
append 一些東西(例如病毒,但在這種情況下是數據庫)到可執行文件的末尾存在一個古老的技巧。 可執行文件通常可以正常工作,但您也可以讀取(甚至可能寫入)數據庫。 已經提到的自定義 VFS 可以幫助您完成這項任務。
另一種解決方案可能是將數據庫視為一種資源,例如 Windows 資源或 Qt 資源。 然后,您可以將數據庫壓縮/編譯為可執行文件。 訪問資源(數據庫)將取決於您使用的框架。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.