当前位置: 首页 > news >正文

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&#xff09;下载cmake并安装 下载路径: https://cmake.org/download/2&#xff09;下载leveldb源码 git clone https://github.com/google/leveldb.git3&#xff09;下载googletest和benchmark&#xff0c;cmake编译时需要 # 进入leveldb源码路径下的third_part…...

如何用76行代码写一个AI微信机器人......

本期博客主要介绍如何使用 微信SDK 和 AI聊天接口 &#xff0c;实现 微信机器人功能。 准备 电脑需要安装Go环境&#xff0c;这个可以直接参考菜鸟教程&#xff1a;Go 语言环境安装&#xff0c;知道CSDN的同学基本能在半小时内装好吧…&#xff08;可选&#xff09;一个编译器…...

拿下域控后,我还是对大佬的操作念念不忘

历来攻防演练中&#xff0c;我都笃信一个道理——吃饱了才有力气干活。所以&#xff0c;在清晨的客户现场&#xff0c;当看到大佬满意地吃完了我带来的煎饺&#xff0c;我知道这一战&#xff0c;我们作为攻击队&#xff0c;基本已经拿下了。 虽然说的每一句话都带着一股醋味儿…...

实习-----Mybatis 框架

Mybatis 框架ORM持久化介绍 了解什么是“持久化”即把数据&#xff08;如内存中的对象&#xff09;保存的磁盘的某一文件中ORM概念ORM&#xff0c;即Object Relational Mapping&#xff0c;它是对象关系映射的简称。它的作用是在关系型数据库和对象之间作一个映射&#xff0c;是…...

【Linux】孤儿进程 | 环境变量 | 命令行参数 | 进程优先级

文章目录1. 孤儿进程2. 环境变量1. PATH环境变量证明ls是系统指令修改自己写的可执行程序对应路径2. env——查看系统环境变量3. 获取环境变量envpenvirongetenv 函数获取 (主流)4. 总结3 . 命令行参数理解命令行参数4. 进程优先级优先级与权限的区分为什么会有优先级&#xff…...

Matlab字符串相关操作-拼接、格式化

常见的有三种方法&#xff1a;向量拼接、strcat函数和sprintf函数1、向量拼接在matlab中字符串本质上也是一个向量&#xff0c;可以通过矩阵运算来实现字符串的拼接&#xff0c;这里随便输入两个字符串a1和b1&#xff0c;用矩阵形式进行拼接&#xff1a;a1 I love;b1 Matlab…...

死磕Spring系列,SpringBoot启动流程

参考文章&#xff1a;SpringBoot启动流程系列讲解 参考视频&#xff1a;SpringBoot启动流程 吐血推荐视频&#xff1a;史上最完整的Spring启动流程 超级好文&#xff1a;SpringBoot执行原理 参考文章&#xff1a;SpringBoot资源接口ResourceLoader和Resource学习 参考文章&…...

关于条件变量wait操作中锁的作用

condition_variable::wait的锁 在看C Concurrency in Action 6.2.3节的线程安全队列时&#xff0c;其对condition_variable的使用与常规用法有点不同&#xff0c;我对condition_variable::wait中锁的作用产生了疑惑&#xff1a;它究竟是保护的谁&#xff1f;于是找到了 C noti…...

JUC并发编程与源码分析笔记09-原子类操作之十八罗汉增强

基本类型原子类 AtomicInteger、AtomicBoolean、AtomicLong。 常用API&#xff1a; public final int get();// 获取当前的值 public final int getAndSet(int newValue);// 获取当前值&#xff0c;并设置新值 public final int getAndIncrement();// 获取当前的值&#xff0…...

含分布式电源的配电网日前两阶段优化调度模型(Matlab代码实现)

&#x1f468;‍&#x1f393;个人主页&#xff1a;研学社的博客&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5;&#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密…...

FreeRTOS的Delay函数

两个Delay函数有两个延时函数vTaskDelay&#xff1a;至少等待指定个数的Tick Interrupt才能变为就绪态xTaskDelayUtil&#xff1a;等待到指定的绝对时刻&#xff0c;才能变为就绪态个人感觉这两个延时函数就是&#xff0c;比如一个我等3个小时&#xff0c;一个是我等到下午3点的…...

HCIA-HarmonyOS Application Developer——题目集1

题目1 1、一位开发人员在设计应用程序时&#xff0c;添加了一个Text组件和Button组件&#xff0c;开发样图如下所示。该开发者不能选择哪种布局方式来放置组件? A、StackLayout B、DependentLayout C、DirectionalLayout D、TableLayout 解析&#xff1a;&#xff08;A&#…...

高性能 Message ToJavaBean 工具 【easy.server.mapper】

easy.server.mapper 介绍 后端开发中&#xff0c;消息转换常见问题 Map 中的数据 转换成实体Bean数组 中的数据 转换成实体BeanServet 中的 param 转换成实体Bean 以上的三个问题是最常见的消息转换困扰。 以Map 举例 常见做法是 手动转换 Map<String,Object> da…...

Web前端学习:三 - 练习

三六&#xff1a;风筝效果 <!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 采用了什么设计模式?

答案是采用了原型模式。原型模式的好处在于方便地拷贝某个实例的属性进行使用、又不会对原实例造成影响&#xff0c;其逻辑在于对 Cloneable 接口的实现。 话不多说看下 Intent 的关键源码&#xff1a; // frameworks/base/core/java/android/content/Intent.java public cla…...

Java数据类型与变量

个人主页&#xff1a;平行线也会相交 欢迎 点赞&#x1f44d; 收藏✨ 留言✉ 加关注&#x1f493;本文由 平行线也会相交 原创 收录于专栏【JavaSE_primary】 文章目录字面常量数据类型变量整型变量字节型变量浮点数变量双精度浮点数单精度浮点数字符型变量布尔型变量空常量nu…...

Python为CANoe工程添加/删除DBC文件

前面文章我们对于通过COM来实现打开CANoe、导入CANoe配置工程、导入执行文件、启动CANoe软件和执行脚本;但是这只能完成最基本的功能调用,在实际得到使用过程中,特别是各家在推的CI/CD以及平台化,仅仅是实现这些功能是完全不够用的;比如dbc的添加和删除,这是我们非常必要…...

不同的产品经理特征和需要的能力

产品经理是一个管家&#xff0c;需要和各方沟通推动产品各个决策进展。 每天早上看看线上用户数据、看下今天要安排任务&#xff0c;接着就是和各方开会讨论推动产品实现。每天穿插于与 UI、用户以及完成自己的 todolist 中循环。如果公司体制完善&#xff0c;还要和运营、数据…...

webpack之处理样式资源

处理样式资源 本章节我们学习使用 Webpack 如何处理 Css、Less、Sass、Scss、Styl 样式资源 #介绍 Webpack 本身是不能识别样式资源的&#xff0c;所以我们需要借助 Loader 来帮助 Webpack 解析样式资源 我们找 Loader 都应该去官方文档中找到对应的 Loader&#xff0c;然后…...

Golang 接口笔记

基本介绍接口是一个数据类型&#xff0c;可以定义一组方法&#xff0c;但都不需要实现。并且interface中不能包含任何变量。到某个自定义类型要使用的时候&#xff0c;再根据具体情况把这些方法实现出来语法type 接口名 interface {method1(参数列表) 返回值列表method2(参数列…...

Java 语言特性(面试系列2)

一、SQL 基础 1. 复杂查询 &#xff08;1&#xff09;连接查询&#xff08;JOIN&#xff09; 内连接&#xff08;INNER JOIN&#xff09;&#xff1a;返回两表匹配的记录。 SELECT e.name, d.dept_name FROM employees e INNER JOIN departments d ON e.dept_id d.dept_id; 左…...

CTF show Web 红包题第六弹

提示 1.不是SQL注入 2.需要找关键源码 思路 进入页面发现是一个登录框&#xff0c;很难让人不联想到SQL注入&#xff0c;但提示都说了不是SQL注入&#xff0c;所以就不往这方面想了 ​ 先查看一下网页源码&#xff0c;发现一段JavaScript代码&#xff0c;有一个关键类ctfs…...

DeepSeek 赋能智慧能源:微电网优化调度的智能革新路径

目录 一、智慧能源微电网优化调度概述1.1 智慧能源微电网概念1.2 优化调度的重要性1.3 目前面临的挑战 二、DeepSeek 技术探秘2.1 DeepSeek 技术原理2.2 DeepSeek 独特优势2.3 DeepSeek 在 AI 领域地位 三、DeepSeek 在微电网优化调度中的应用剖析3.1 数据处理与分析3.2 预测与…...

CMake基础:构建流程详解

目录 1.CMake构建过程的基本流程 2.CMake构建的具体步骤 2.1.创建构建目录 2.2.使用 CMake 生成构建文件 2.3.编译和构建 2.4.清理构建文件 2.5.重新配置和构建 3.跨平台构建示例 4.工具链与交叉编译 5.CMake构建后的项目结构解析 5.1.CMake构建后的目录结构 5.2.构…...

STM32F4基本定时器使用和原理详解

STM32F4基本定时器使用和原理详解 前言如何确定定时器挂载在哪条时钟线上配置及使用方法参数配置PrescalerCounter ModeCounter Periodauto-reload preloadTrigger Event Selection 中断配置生成的代码及使用方法初始化代码基本定时器触发DCA或者ADC的代码讲解中断代码定时启动…...

【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】

1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件&#xff08;System Property Definition File&#xff09;&#xff0c;用于声明和管理 Bluetooth 模块相…...

UR 协作机器人「三剑客」:精密轻量担当(UR7e)、全能协作主力(UR12e)、重型任务专家(UR15)

UR协作机器人正以其卓越性能在现代制造业自动化中扮演重要角色。UR7e、UR12e和UR15通过创新技术和精准设计满足了不同行业的多样化需求。其中&#xff0c;UR15以其速度、精度及人工智能准备能力成为自动化领域的重要突破。UR7e和UR12e则在负载规格和市场定位上不断优化&#xf…...

华为云Flexus+DeepSeek征文|DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建

华为云FlexusDeepSeek征文&#xff5c;DeepSeek-V3/R1 商用服务开通全流程与本地部署搭建 前言 如今大模型其性能出色&#xff0c;华为云 ModelArts Studio_MaaS大模型即服务平台华为云内置了大模型&#xff0c;能助力我们轻松驾驭 DeepSeek-V3/R1&#xff0c;本文中将分享如何…...

mysql已经安装,但是通过rpm -q 没有找mysql相关的已安装包

文章目录 现象&#xff1a;mysql已经安装&#xff0c;但是通过rpm -q 没有找mysql相关的已安装包遇到 rpm 命令找不到已经安装的 MySQL 包时&#xff0c;可能是因为以下几个原因&#xff1a;1.MySQL 不是通过 RPM 包安装的2.RPM 数据库损坏3.使用了不同的包名或路径4.使用其他包…...

Linux 中如何提取压缩文件 ?

Linux 是一种流行的开源操作系统&#xff0c;它提供了许多工具来管理、压缩和解压缩文件。压缩文件有助于节省存储空间&#xff0c;使数据传输更快。本指南将向您展示如何在 Linux 中提取不同类型的压缩文件。 1. Unpacking ZIP Files ZIP 文件是非常常见的&#xff0c;要在 …...