windows下编译leveldb(动态库+静态库)

环境准备

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

猜你喜欢

转载自blog.csdn.net/www_dong/article/details/129213819
今日推荐