环境准备
1)下载cmake并安装
下载路径: https://cmake.org/download/
2)下载leveldb源码
git clone https://github.com/google/leveldb.git
3)下载googletest和benchmark,cmake编译时需要
# 进入leveldb源码路径下的third_party
cd leveldb/third_party
# 下载googletest
git clone https://github.com/google/googletest.git
# 下载benchmark
git clone https://github.com/google/benchmark.git
生成工程文件
1)进入leveldb源码目录,以管理员方式打开cmd.exe,执行
cmake CMakeLists.txt
生成工程文件如下所示:
静态库编译
配置
无需任何配置,使用visual studio打开工程文件leveldb.sln直接编译即可。
生成
如编译debug版本,编译完成后在源码根目录的Debug文件夹下会生成对应的静态库。
测试
#include <iostream>
#include "leveldb/db.h"
#include "leveldb/write_batch.h"
using namespace std;
int main()
{
leveldb::DB* dbptr = nullptr;
leveldb::Options options;
options.create_if_missing = true;
// open
leveldb::Status status = leveldb::DB::Open(options, "./leveldb.db", &dbptr);
if (!status.ok())
{
// 失败返回状态字符串
cout << "Open db failed, status: " << status.ToString() << endl;
return -1;
}
assert(nullptr != dbptr);
cout << "Open db success" << endl;
// put
leveldb::WriteOptions putOptions;
putOptions.sync = true;
status = dbptr->Put(putOptions, "TEST1", "RESULT1");
if (!status.ok())
{
cout << "Put failed, status: " << status.ToString() << endl;
return -1;
}
cout << "Put success" << endl;
// write
leveldb::WriteBatch writeBatch;
writeBatch.Put("name", "lucas");
writeBatch.Put("age", "12");
writeBatch.Put("sex", "boy");
status = dbptr->Write(leveldb::WriteOptions(), &writeBatch);
if (!status.ok())
{
cout << "Write failed, status: " << status.ToString() << endl;
return -1;
}
cout << "Write success" << endl;
// get
leveldb::ReadOptions getOptions;
std::string value;
status = dbptr->Get(getOptions, "TEST1", &value);
if (!status.ok())
{
cout << "Get failed, status: " << status.ToString() << std::endl;
return -1;
}
cout << "Get success, value: " << value << std::endl;
// iter
leveldb::Iterator* it = dbptr->NewIterator(leveldb::ReadOptions());
if (!it)
{
cout << "NewIterator failed" << endl;
return -1;
}
cout << "Iterator test start" << endl;
it->SeekToFirst();
while (it->Valid())
{
leveldb::Slice sKey = it->key();
leveldb::Slice sVal = it->value();
cout << "key:" << sKey.ToString() << " value:" << sVal.ToString() << endl;
it->Next();
}
cout << "Iterator test finish" << endl;
if (it)
{
delete (it);
it = nullptr;
}
// delete
status = dbptr->Delete(putOptions, "TEST1");
if (!status.ok())
{
cout << "Delete failed, status: " << status.ToString() << endl;
return -1;
}
cout << "Delete success, key: " << "TEST1" << endl;
if (dbptr)
{
delete dbptr;
dbptr = nullptr;
}
cout << "test finished" << endl;
system("pause");
return 0;
}
测试结果:
动态库编译
配置
1)修改位置1(配置属性——常规——配置类型):
2)修改位置2(配置属性——高级——目标文件扩展名):
3)修改位置3(配置属性——C/C++——预处理器,增加LEVELDB_SHARED_LIBRARY):
生成
如生成Debug版本,编译完成后在源码根目录的Debug文件夹下会生成对应的动态库。
测试
采用手动加载动态库,这样具有良好的向下兼容性。
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <tchar.h>
#include "leveldb/c.h"
using namespace std;
typedef leveldb_t* (*LevelDBOpen)(const leveldb_options_t*, const char*, char**);
typedef leveldb_options_t* (*LevelDBCreate)(void);
typedef leveldb_writeoptions_t* (*LevelDBWriteOptionsCreate)(void);
typedef leveldb_readoptions_t* (*LevelDBReadOptionsCreate)(void);
typedef void (*LevelDBReadOptionsDestroy)(leveldb_readoptions_t*);
typedef void (*LevelDBPut)(leveldb_t*, const leveldb_writeoptions_t*,
const char*, size_t, const char*,
size_t, char**);
typedef char* (*LevelDBGet)(leveldb_t*, const leveldb_readoptions_t*,
const char*, size_t, size_t*, char**);
typedef void (*LevelDBWrite)(leveldb_t*,
const leveldb_writeoptions_t*,
leveldb_writebatch_t*, char**);
typedef void (*LevelDBDelete)(leveldb_t*,
const leveldb_writeoptions_t*,
const char*, size_t, char**);
typedef void (*LevelDBClose)(leveldb_t*);
typedef void (*LevelDBDestroy)(const leveldb_options_t*,
const char*, char**);
typedef void (*LevelDBSetCreateIfMissing)(leveldb_options_t*, uint8_t);
typedef void (*LevelDBFree)(void*);
typedef leveldb_writebatch_t* (*LevelDBWriteBatchCreate)(void);
typedef void (*LevelDBWriteBatchDestroy)(leveldb_writebatch_t*);
typedef void (*LevelDBWriteBatchPut)(leveldb_writebatch_t*, const char*,
size_t, const char*, size_t);
int main()
{
HMODULE handle = ::LoadLibrary(_T("./leveldb.dll"));
if (!handle)
{
cout << "Load failed!" << endl;
return -1;
}
cout << "Load success" << endl;
// get func
LevelDBOpen func_open = (LevelDBOpen)GetProcAddress(handle, "leveldb_open");
LevelDBCreate func_options_create = (LevelDBCreate)GetProcAddress(handle, "leveldb_options_create");
LevelDBWriteOptionsCreate func_write_options_create =
(LevelDBWriteOptionsCreate)GetProcAddress(handle, "leveldb_writeoptions_create");
LevelDBReadOptionsCreate func_read_options_create =
(LevelDBReadOptionsCreate)GetProcAddress(handle, "leveldb_readoptions_create");
LevelDBReadOptionsDestroy func_read_options_destroy =
(LevelDBReadOptionsDestroy)GetProcAddress(handle, "leveldb_readoptions_destroy");
LevelDBPut func_put = (LevelDBPut)GetProcAddress(handle, "leveldb_put");
LevelDBGet func_get = (LevelDBGet)GetProcAddress(handle, "leveldb_get");
LevelDBWrite func_write =
(LevelDBWrite)GetProcAddress(handle, "leveldb_write");
LevelDBDelete func_delete =
(LevelDBDelete)GetProcAddress(handle, "leveldb_delete");
LevelDBClose func_close =
(LevelDBClose)GetProcAddress(handle, "leveldb_close");
LevelDBDestroy func_destroy =
(LevelDBDestroy)GetProcAddress(handle, "leveldb_destroy_db");
LevelDBSetCreateIfMissing func_options_set_create_if_missing =
(LevelDBSetCreateIfMissing)GetProcAddress(handle, "leveldb_options_set_create_if_missing");
LevelDBFree func_free = (LevelDBFree)GetProcAddress(handle, "leveldb_free");
LevelDBWriteBatchCreate func_writebatch_create =
(LevelDBWriteBatchCreate)GetProcAddress(handle, "leveldb_writebatch_create");
LevelDBWriteBatchDestroy func_writebatch_destroy =
(LevelDBWriteBatchDestroy)GetProcAddress(handle, "leveldb_writebatch_destroy");
LevelDBWriteBatchPut func_writebatch_put =
(LevelDBWriteBatchPut)GetProcAddress(handle, "leveldb_writebatch_put");
if (nullptr == func_open
|| nullptr == func_options_create
|| nullptr == func_write_options_create
|| nullptr == func_read_options_create
|| nullptr == func_read_options_destroy
|| nullptr == func_put
|| nullptr == func_get
|| nullptr == func_delete
|| nullptr == func_close
|| nullptr == func_destroy
|| nullptr == func_options_set_create_if_missing
|| nullptr == func_free
|| nullptr == func_writebatch_create
|| nullptr == func_writebatch_destroy
|| nullptr == func_writebatch_put)
{
DWORD dw = GetLastError();
cout << "Get func failed, err: " << dw << endl;
return -1;
}
cout << "Open func success" << endl;
// Open
char* err = nullptr;
leveldb_options_t* options = nullptr;
options = func_options_create();
func_options_set_create_if_missing(options, 1);
leveldb_t* db = func_open(options, "./leveldb.db", &err);
if (nullptr != err)
{
cout << "Open failed, err: " << err << endl;
return -1;
}
func_free(err);
err = nullptr;
cout << "Open success" << endl;
// Put
leveldb_writeoptions_t* woptions = nullptr;
woptions = func_write_options_create();
func_put(db, woptions, "key", 5, "value", 5, &err);
if (nullptr != err)
{
cout << "Put failed, err: " << err << endl;
return -1;
}
func_free(err);
err = nullptr;
cout << "Put success" << endl;
leveldb_writebatch_t* batch = func_writebatch_create();
func_writebatch_put(batch, "foo", 3, "a", 1);
func_writebatch_put(batch, "bar", 3, "b", 1);
func_writebatch_put(batch, "box", 3, "c", 1);
func_write(db, woptions, batch, &err);
if (nullptr != err)
{
cout << "Write failed, err: " << err << endl;
return -1;
}
func_free(err);
err = nullptr;
func_writebatch_destroy(batch);
cout << "Write success" << endl;
// Read
size_t read_len = 0;
leveldb_readoptions_t* roptions = func_read_options_create();
char* read = func_get(db, roptions, "key", 5, &read_len, &err);
if (nullptr != err)
{
cout << "Read failed!" << endl;
return -1;
}
func_free(err);
err = nullptr;
func_read_options_destroy(roptions);
cout << "Read success" << endl;
// Delete
func_delete(db, woptions, "key", 3, &err);
if (nullptr != err)
{
cout << "Delete failed!" << endl;
return -1;
}
func_free(err);
err = nullptr;
cout << "Delete success" << endl;
// Close
func_close(db);
cout << "Close success" << endl;
// Destroy
func_destroy(options, "./leveldb.db", &err);
if (nullptr != err)
{
cout << "Destroy failed!" << endl;
return -1;
}
func_free(err);
err = nullptr;
cout << "Destroy success" << endl;
FreeLibrary(handle);
system("pause");
return 0;
}
测试结果:
参考:
leveldb介绍:https://blog.csdn.net/joelcat/article/details/89240584
linux下安装leveldb:https://blog.csdn.net/www_dong/article/details/107307944