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

news2024/10/1 12:19:08

环境准备

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/370203.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

干了2年的手工点点点,感觉每天浑浑噩噩,我的自动化测试之路...

作为一个测试人员&#xff0c;从业年期从事手工测试的工作是没有太多坏处的&#xff0c;当然&#xff0c;如果一直点来点去那么确实自身得不到提高&#xff0c;这时候选择学习自动化测试是一件很有必要的事情&#xff0c;一来将自己从繁重的重复工作中解放出来&#xff0c;从事…

操作系统——6.系统调用

目录 1.概述 2.系统调用的定义和作用 2.1 定义 2.2 功能 2.3 分类 3.系统调用和库函数的区别 4.系统调用背后的过程 5.小结 1.概述 这篇文章我们主要来介绍一下操作系统中的系统调用&#xff0c;下面来看一下具体的框架图&#xff1a; 2.系统调用的定义和作用 2.1 定…

Mysql索引学习

1. 索引 1.1 索引概述 MySQL官方对索引的定义为&#xff1a;索引&#xff08;index&#xff09;是帮助MySQL高效获取数据的数据结构&#xff08;有序&#xff09;。在数据之外&#xff0c;数据库系统还维护者满足特定查找算法的数据结构&#xff0c;这些数据结构以某种方式引…

Linux->进程优先级

目录 1. 优先级的概念 2. 优先级的运作方式 3. Linux下查看进程优先级以及调整 3.1 查看进程优先级 3.2 修改进程优先级 1. 优先级的概念 1. cpu资源分配的先后顺序&#xff0c;就是指进程的优先权&#xff08;priority&#xff09;。 2. 优先权高的进程有优先执行权利。配…

数据结构:二叉树概念篇(算法基础)

目录 一.有向树的图论基础 1.有向树的相关基本概念 有向树的基本定义: 有向树的结点的度&#xff1a; 有向树的度: 有向树的根结点,分枝结点,叶结点: 树的子树: 树结点的层次: 树的高度: 2.一个基本的数学结论 3.有序有向树 二.数据结构中树的顺序存储结构与链式存…

【华为OD机试模拟题】用 C++ 实现 - 星际篮球争霸赛(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

【log】操作类日志处理 与 报错类日志处理logback

文章目录一、操作类日志处理【环绕增强】aop环绕增强导包第一步&#xff1a;自定义注解interface第二步&#xff1a;在Controller写一个测试的方法&#xff1a;第三步&#xff1a;编写LogAspect增强类与增强方法日志写入数据库&#xff08;使用mybatis&#xff09;第一步&#…

C/C++每日一练(20230225)

目录 1. 工龄问题求解 ★ 2. 字符图形输出 ★★ 3. LRU 缓存机制 ★★★ 1. 工龄问题求解 给定公司N名员工的工龄&#xff0c;要求按工龄增序输出每个工龄段有多少员工。输入首先给出正整数N&#xff0c;即员工总人数&#xff1b; 随后给出N个整数&#xff0c;即每个员工…

图像分割评价指标:Dice和MIoU

目录Dice理论代码MIou理论查准率 precison查全率 recallMIoU 平均交并比代码高效的矩阵运算低效的好理解的计算混淆矩阵Dice和MIoU两者的关系参考链接Dice 理论 Dice用来衡量预测结果pred和标签label的相似度&#xff0c;公式如下图所示&#xff0c;即两个集合的交集/并集。 …

Java-多线程-增强篇-锁强化第3篇

Java集合框架中的锁 今天我们继续来学习锁 字符串操作中的锁 String是线程安全的&#xff0c;因为使用final修饰Stringbuilder 是线程不安全的&#xff0c;其方法没有使用synchronized修饰StringBuffer 是线程安全的&#xff0c;其方法使用synchronized修饰 List集合中的锁 …

【人工智能 AI】可以从 RPA 中受益的 10 个行业 10 Industries That Can Benefit From RPA

目录 RPA技术介绍 Which industries can use robotic process automation?哪些行业可以使用机器人过程自动化? Robotic process automation in the retail industry零售业中的机器人过程自动化 Robotic process automation in the construction industry建筑行业的机器人…

RebbitMQ 消息队列(高级应用)

RabbitMQ 高级特性 消息可靠性投递&#xff0c;consumer ACK&#xff0c;消费端限流&#xff0c;TTL&#xff0c;死信队列&#xff0c;延迟队列&#xff0c;日志与监控&#xff0c;消息可靠性与追踪&#xff0c;管理 RabbitMQ 应用问题 消息可靠性保障&#xff0c;消息幂等性…

JavaScript 基础【快速掌握知识点】

目录 为什么要学JavaScript? 什么是JavaScript 特点&#xff1a; 组成&#xff1a; JavaScript的基本结构 基本结构 内部引用 外部引用 console对象进行输出 JavaScript核心语法 1、变量声明 2、数据类型 3、运算符 4、条件语句 5、循环语句 6、数组 7…

【shell】for while 循环的例子,快速了解

for 循环读一个文件的每一行 for i in cat temp.list;do echo $i;done for ip in $(cat ip.list);do ping -c 2 $ip;done循环打印数字 for a in {1…5};do echo $a;done for a in {1…5…2};do echo $a;done #等差 for a in $(seq 1 5);do echo $a;done for a in $(seq 1 2 5)…

内网穿透常用方法系列总结

前言在内网渗透时&#xff0c;一个WebShell或CobaltStrike、Metasploit上线等&#xff0c;只是开端&#xff0c;更多是要内网横向移动&#xff0c;扩大战果&#xff0c;打到核心区域。但后渗透的前提是需要搭建一条通向内网的“专属通道”&#xff0c;才能进一步攻击。可实战中…

【华为OD机试模拟题】用 C++ 实现 - 找出重复代码(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

C语言static关键字

目录static修饰局部变量static修饰全局变量static修饰函数static是C语言的关键字&#xff0c;它有静态的意思static的三种用法&#xff1a;修饰局部变量修饰全局变量修饰函数 static修饰局部变量 我们先看一个程序&#xff1a; void print() {int a 0;a;printf("%d\n&…

【华为OD机试模拟题】用 C++ 实现 - 数组组成的最小数字(2023.Q1)

最近更新的博客 华为OD机试 - 入栈出栈(C++) | 附带编码思路 【2023】 华为OD机试 - 箱子之形摆放(C++) | 附带编码思路 【2023】 华为OD机试 - 简易内存池 2(C++) | 附带编码思路 【2023】 华为OD机试 - 第 N 个排列(C++) | 附带编码思路 【2023】 华为OD机试 - 考古…

更改tomcat访问端口()

1Centos7开启端口 查看防火墙状态命令&#xff1a; systemctl status firewalld 启动防火墙命令&#xff1a; systemctl start firewalld 关闭防火墙命令&#xff1a; systemctl stop firewalld 开放端口命令&#xff1a; firewall-cmd --zonepublic --add-port5011/tcp --pe…

23、高自由度下的E类波形理论计算(附Matlab代码)

23、高自由度下的E类波形理论计算&#xff08;附Matlab代码&#xff09; 0、代码 任意占空比、电压导数条件下的E类波形与阻抗条件计算Matlab 注意修改路径&#xff0c;我这边是&#xff1a;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#xff01;&#…