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(参数列…...
SDXL-Turbo实战教程:从A futuristic car到motorcycle的删改逻辑教学
SDXL-Turbo实战教程:从A futuristic car到motorcycle的删改逻辑教学 获取更多AI镜像 想探索更多AI镜像和应用场景?访问 CSDN星图镜像广场,提供丰富的预置镜像,覆盖大模型推理、图像生成、视频生成、模型微调等多个领域,…...
不止是缓存:深入Quartus FIFO IP核,玩转Show-ahead与Normal模式下的数据吞吐率优化
深入解析Quartus FIFO IP核:Show-ahead与Normal模式下的性能优化实战 在FPGA开发中,数据流处理系统的性能瓶颈往往出现在数据缓冲环节。作为Intel Quartus Prime工具链中的关键IP核,FIFO(First In First Out)缓冲器的…...
如何突破B站视频获取限制?这款开源工具让你轻松搞定
如何突破B站视频获取限制?这款开源工具让你轻松搞定 【免费下载链接】bilibili-parse bilibili Video API 项目地址: https://gitcode.com/gh_mirrors/bi/bilibili-parse 你是否遇到过想要保存B站精彩视频却无从下手的困境?是否因复杂的技术门槛而…...
App 测试用例覆盖率提升检查清单
App 测试用例覆盖率提升检查清单 核心用途:核对现有测试用例,快速找出「需求、功能、非功能、移动端特有场景」的覆盖遗漏点,适配 App UI 自动化手动测试,兼顾 PO 模型、数据驱动、各类用例设计方法(等价类/边界值等&a…...
别再为UI动画发愁了!用Spine+Unity 2021制作丝滑2D动画的保姆级流程
SpineUnity 2021:打造专业级2D UI动画的完整实战指南 在独立游戏开发领域,UI动画的质量往往决定着玩家的第一印象。那些流畅的按钮反馈、生动的界面过渡,不仅提升了产品质感,更直接影响着用户的留存率。然而对于资源有限的中小团队…...
VoxCPM-1.5-WEBUI问题解决:部署常见错误与一键启动脚本详解
VoxCPM-1.5-WEBUI问题解决:部署常见错误与一键启动脚本详解 1. 快速入门指南 1.1 镜像部署准备 在开始使用VoxCPM-1.5-WEBUI之前,您需要确保具备以下条件: 支持CUDA的NVIDIA显卡(建议RTX 3060及以上)至少16GB系统内…...
【大英赛】2009-2026年大英赛ABCD类历年真题、样卷、听力音频及答案PDF电子版
2026年大英赛将于4月12日9:00—11:00举行,开始倒计时啦!小编整理了最新的2009-2026年大学生英语竞赛(大英赛NECCS)ABCD类历年真题、样卷、听力音频及答案解析,PDF电子版,可下载打印! 资料下载&a…...
终极指南:如何在Windows 10上免费安装Android子系统
终极指南:如何在Windows 10上免费安装Android子系统 【免费下载链接】WSA-Windows-10 This is a backport of Windows Subsystem for Android to Windows 10. 项目地址: https://gitcode.com/gh_mirrors/ws/WSA-Windows-10 想在Windows 10电脑上畅玩手机游戏…...
Wan2.2-I2V-A14B效果对比:LSTM时序预测辅助下的动态剧情生成
Wan2.2-I2V-A14B效果对比:LSTM时序预测辅助下的动态剧情生成 1. 引言 想象一下,当你输入一段文字描述,AI不仅能生成对应的视频,还能像专业导演一样把控剧情节奏和情感起伏。这正是Wan2.2-I2V-A14B结合LSTM时序预测技术带来的突破…...
视频号推客模式系统小程序开发
开发一个基于微信视频号的推客模式系统小程序,需要结合微信生态的开放能力和推客(分销)模式的业务逻辑。以下是关键开发要点:微信小程序与视频号打通通过微信开放平台的JS-SDK实现小程序与视频号的互联互通。调用wx.openChannelsA…...
