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;// putleveldb::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;// getleveldb::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;// iterleveldb::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;}// deletestatus = 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 funcLevelDBOpen 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;// Openchar* 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;// Putleveldb_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;// Readsize_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;// Deletefunc_delete(db, woptions, "key", 3, &err);if (nullptr != err) {cout << "Delete failed!" << endl;return -1;}func_free(err);err = nullptr;cout << "Delete success" << endl;// Closefunc_close(db);cout << "Close success" << endl;// Destroyfunc_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
相关文章:
windows下编译leveldb(动态库+静态库)
环境准备 1)下载cmake并安装 下载路径: https://cmake.org/download/2)下载leveldb源码 git clone https://github.com/google/leveldb.git3)下载googletest和benchmark,cmake编译时需要 # 进入leveldb源码路径下的third_part…...
如何用76行代码写一个AI微信机器人......
本期博客主要介绍如何使用 微信SDK 和 AI聊天接口 ,实现 微信机器人功能。 准备 电脑需要安装Go环境,这个可以直接参考菜鸟教程:Go 语言环境安装,知道CSDN的同学基本能在半小时内装好吧…(可选)一个编译器…...
拿下域控后,我还是对大佬的操作念念不忘
历来攻防演练中,我都笃信一个道理——吃饱了才有力气干活。所以,在清晨的客户现场,当看到大佬满意地吃完了我带来的煎饺,我知道这一战,我们作为攻击队,基本已经拿下了。 虽然说的每一句话都带着一股醋味儿…...
实习-----Mybatis 框架
Mybatis 框架ORM持久化介绍 了解什么是“持久化”即把数据(如内存中的对象)保存的磁盘的某一文件中ORM概念ORM,即Object Relational Mapping,它是对象关系映射的简称。它的作用是在关系型数据库和对象之间作一个映射,是…...
【Linux】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级
文章目录1. 孤儿进程2. 环境变量1. PATH环境变量证明ls是系统指令修改自己写的可执行程序对应路径2. env——查看系统环境变量3. 获取环境变量envpenvirongetenv 函数获取 (主流)4. 总结3 . 命令行参数理解命令行参数4. 进程优先级优先级与权限的区分为什么会有优先级ÿ…...
Matlab字符串相关操作-拼接、格式化
常见的有三种方法:向量拼接、strcat函数和sprintf函数1、向量拼接在matlab中字符串本质上也是一个向量,可以通过矩阵运算来实现字符串的拼接,这里随便输入两个字符串a1和b1,用矩阵形式进行拼接:a1 I love;b1 Matlab…...
死磕Spring系列,SpringBoot启动流程
参考文章:SpringBoot启动流程系列讲解 参考视频:SpringBoot启动流程 吐血推荐视频:史上最完整的Spring启动流程 超级好文:SpringBoot执行原理 参考文章:SpringBoot资源接口ResourceLoader和Resource学习 参考文章&…...
关于条件变量wait操作中锁的作用
condition_variable::wait的锁 在看C Concurrency in Action 6.2.3节的线程安全队列时,其对condition_variable的使用与常规用法有点不同,我对condition_variable::wait中锁的作用产生了疑惑:它究竟是保护的谁?于是找到了 C noti…...
JUC并发编程与源码分析笔记09-原子类操作之十八罗汉增强
基本类型原子类 AtomicInteger、AtomicBoolean、AtomicLong。 常用API: public final int get();// 获取当前的值 public final int getAndSet(int newValue);// 获取当前值,并设置新值 public final int getAndIncrement();// 获取当前的值࿰…...
含分布式电源的配电网日前两阶段优化调度模型(Matlab代码实现)
👨🎓个人主页:研学社的博客💥💥💞💞欢迎来到本博客❤️❤️💥💥🏆博主优势:🌞🌞🌞博客内容尽量做到思维缜密…...
FreeRTOS的Delay函数
两个Delay函数有两个延时函数vTaskDelay:至少等待指定个数的Tick Interrupt才能变为就绪态xTaskDelayUtil:等待到指定的绝对时刻,才能变为就绪态个人感觉这两个延时函数就是,比如一个我等3个小时,一个是我等到下午3点的…...
HCIA-HarmonyOS Application Developer——题目集1
题目1 1、一位开发人员在设计应用程序时,添加了一个Text组件和Button组件,开发样图如下所示。该开发者不能选择哪种布局方式来放置组件? A、StackLayout B、DependentLayout C、DirectionalLayout D、TableLayout 解析:(A&#…...
高性能 Message ToJavaBean 工具 【easy.server.mapper】
easy.server.mapper 介绍 后端开发中,消息转换常见问题 Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean 以上的三个问题是最常见的消息转换困扰。 以Map 举例 常见做法是 手动转换 Map<String,Object> da…...
Web前端学习:三 - 练习
三六:风筝效果 <!DOCTYPE html> <html><head><meta charset"utf-8"><title></title><style type"text/css">*{margin: 0;padding: 0;}.d1{width: 200px;height: 200px;background: yellow;position…...
面试题:Android 中 Intent 采用了什么设计模式?
答案是采用了原型模式。原型模式的好处在于方便地拷贝某个实例的属性进行使用、又不会对原实例造成影响,其逻辑在于对 Cloneable 接口的实现。 话不多说看下 Intent 的关键源码: // frameworks/base/core/java/android/content/Intent.java public cla…...
Java数据类型与变量
个人主页:平行线也会相交 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 平行线也会相交 原创 收录于专栏【JavaSE_primary】 文章目录字面常量数据类型变量整型变量字节型变量浮点数变量双精度浮点数单精度浮点数字符型变量布尔型变量空常量nu…...
Python为CANoe工程添加/删除DBC文件
前面文章我们对于通过COM来实现打开CANoe、导入CANoe配置工程、导入执行文件、启动CANoe软件和执行脚本;但是这只能完成最基本的功能调用,在实际得到使用过程中,特别是各家在推的CI/CD以及平台化,仅仅是实现这些功能是完全不够用的;比如dbc的添加和删除,这是我们非常必要…...
不同的产品经理特征和需要的能力
产品经理是一个管家,需要和各方沟通推动产品各个决策进展。 每天早上看看线上用户数据、看下今天要安排任务,接着就是和各方开会讨论推动产品实现。每天穿插于与 UI、用户以及完成自己的 todolist 中循环。如果公司体制完善,还要和运营、数据…...
webpack之处理样式资源
处理样式资源 本章节我们学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 样式资源 #介绍 Webpack 本身是不能识别样式资源的,所以我们需要借助 Loader 来帮助 Webpack 解析样式资源 我们找 Loader 都应该去官方文档中找到对应的 Loader,然后…...
Golang 接口笔记
基本介绍接口是一个数据类型,可以定义一组方法,但都不需要实现。并且interface中不能包含任何变量。到某个自定义类型要使用的时候,再根据具体情况把这些方法实现出来语法type 接口名 interface {method1(参数列表) 返回值列表method2(参数列…...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...
2024年赣州旅游投资集团社会招聘笔试真
2024年赣州旅游投资集团社会招聘笔试真 题 ( 满 分 1 0 0 分 时 间 1 2 0 分 钟 ) 一、单选题(每题只有一个正确答案,答错、不答或多答均不得分) 1.纪要的特点不包括()。 A.概括重点 B.指导传达 C. 客观纪实 D.有言必录 【答案】: D 2.1864年,()预言了电磁波的存在,并指出…...
【Zephyr 系列 10】实战项目:打造一个蓝牙传感器终端 + 网关系统(完整架构与全栈实现)
🧠关键词:Zephyr、BLE、终端、网关、广播、连接、传感器、数据采集、低功耗、系统集成 📌目标读者:希望基于 Zephyr 构建 BLE 系统架构、实现终端与网关协作、具备产品交付能力的开发者 📊篇幅字数:约 5200 字 ✨ 项目总览 在物联网实际项目中,**“终端 + 网关”**是…...
RNN避坑指南:从数学推导到LSTM/GRU工业级部署实战流程
本文较长,建议点赞收藏,以免遗失。更多AI大模型应用开发学习视频及资料,尽在聚客AI学院。 本文全面剖析RNN核心原理,深入讲解梯度消失/爆炸问题,并通过LSTM/GRU结构实现解决方案,提供时间序列预测和文本生成…...
WebRTC从入门到实践 - 零基础教程
WebRTC从入门到实践 - 零基础教程 目录 WebRTC简介 基础概念 工作原理 开发环境搭建 基础实践 三个实战案例 常见问题解答 1. WebRTC简介 1.1 什么是WebRTC? WebRTC(Web Real-Time Communication)是一个支持网页浏览器进行实时语音…...
pikachu靶场通关笔记19 SQL注入02-字符型注入(GET)
目录 一、SQL注入 二、字符型SQL注入 三、字符型注入与数字型注入 四、源码分析 五、渗透实战 1、渗透准备 2、SQL注入探测 (1)输入单引号 (2)万能注入语句 3、获取回显列orderby 4、获取数据库名database 5、获取表名…...
Kubernetes 网络模型深度解析:Pod IP 与 Service 的负载均衡机制,Service到底是什么?
Pod IP 的本质与特性 Pod IP 的定位 纯端点地址:Pod IP 是分配给 Pod 网络命名空间的真实 IP 地址(如 10.244.1.2)无特殊名称:在 Kubernetes 中,它通常被称为 “Pod IP” 或 “容器 IP”生命周期:与 Pod …...
恶补电源:1.电桥
一、元器件的选择 搜索并选择电桥,再multisim中选择FWB,就有各种型号的电桥: 电桥是用来干嘛的呢? 它是一个由四个二极管搭成的“桥梁”形状的电路,用来把交流电(AC)变成直流电(DC)。…...
怎么开发一个网络协议模块(C语言框架)之(六) ——通用对象池总结(核心)
+---------------------------+ | operEntryTbl[] | ← 操作对象池 (对象数组) +---------------------------+ | 0 | 1 | 2 | ... | N-1 | +---------------------------+↓ 初始化时全部加入 +------------------------+ +-------------------------+ | …...
