https://curl.haxx.se/libcurl/c/libcurl-tutorial.html

基础

初始化,参数指定要初始化的模块:

1
curl_global_init(CURL_GLOBAL_ALL);

如果没有调用 curl_global_initcurl_easy_perform 会自动调用。

1
2
CURL_GLOBAL_WIN32
CURL_GLOBAL_SSL

当不再使用 libcurl 时调用:

1
curl_global_cleanup();

init 和 cleanup 避免重复调用,应只调用一次。

查询libcurl支持的特性:

1
curl_version_info();

libcurl 提供两种接口:

  1. easy interface - 函数以 curl_easy 为前缀,同步、阻塞调用。(let you do single transfers with a synchronous and blocking function call)
  2. multi interface - 支持在一个线程中多个传输任务,异步。(allows multiple simultaneous transfers in a single thread)
阅读全文 »

基础概念

https://www.ruanyifeng.com/blog/2020/01/ffmpeg.html

码率

比特率,bps,每秒位数。

muxer

封装,把视频流、音频流、字幕流等封装到一个容器格式中。

demuxer

从容器格式中分离出流。

容器

视频文件本身其实是一个容器(container),里面包括了视频和音频,也可能有字幕等其他内容。

查看 ffmpeg 支持的容器:

1
ffmpeg -formats

编码格式

视频和音频都需要经过编码,才能保存成文件。不同的编码格式(CODEC),有不同的压缩率,会导致文件大小和清晰度的差异。比如H.264就是一种视频编码格式。

查看 ffmpeg 支持的编码格式:

1
ffmpeg -codecs
阅读全文 »

http://rapidjson.org/zh-cn/

用法一览

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
// rapidjson/example/simpledom/simpledom.cpp
#include "rapidjson/document.h"
#include "rapidjson/writer.h"
#include "rapidjson/stringbuffer.h"
#include <iostream>

using namespace rapidjson;

int main() {
// 1. Parse a JSON string into DOM.
const char* json = "{\"project\":\"rapidjson\",\"stars\":10}";
Document d;
d.Parse(json);

// 2. Modify it by DOM.
Value& s = d["stars"];
s.SetInt(s.GetInt() + 1);

// 3. Stringify the DOM
StringBuffer buffer;
Writer<StringBuffer> writer(buffer);
d.Accept(writer);

// Output {"project":"rapidjson","stars":11}
std::cout << buffer.GetString() << std::endl;
return 0;
}
阅读全文 »

https://github.com/nlohmann/json/
https://json.nlohmann.me/features/arbitrary_types/

创建 json 对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
// create an empty structure (null)
json j;

// add a number that is stored as double (note the implicit conversion of j to an object)
j["pi"] = 3.141;

// add a Boolean that is stored as bool
j["happy"] = true;

// add a string that is stored as std::string
j["name"] = "Niels";

// add another null object by passing nullptr
j["nothing"] = nullptr;

// add an object inside the object
j["answer"]["everything"] = 42;

// add an array that is stored as std::vector (using an initializer list)
j["list"] = { 1, 0, 2 };

// add another object (using an initializer list of pairs)
j["object"] = { {"currency", "USD"}, {"value", 42.99} };

// instead, you could also write (which looks very similar to the JSON above)
json j2 = {
{"pi", 3.141},
{"happy", true},
{"name", "Niels"},
{"nothing", nullptr},
{"answer", {
{"everything", 42}
}},
{"list", {1, 0, 2}},
{"object", {
{"currency", "USD"},
{"value", 42.99}
}}
};
阅读全文 »

https://developers.google.cn/protocol-buffers/docs/cpptutorial

简介

首先编写.proto文件定义数据结构,然后用protobuf工具生成对应编程语言的序列化和反序列化代码。

随着数据格式版本的更新,protobuf会自动处理对旧格式的兼容。

定义 .proto 文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
syntax = "proto2"

package tutorial

message Person {
optional string name = 1;
optional int32 id = 2;
optional string email = 3;

enum PhoneType {
MOBILE = 0;
HOME = 1;
WORK = 2;
}

message PhoneNumber {
optional string number = 1;
optional PhoneType type = 2 [default = HOME];
}

repeated PhoneNumber phones = 4;
}

message AddressBook {
repeated Person people = 1;
}
阅读全文 »

《Head First Go》笔记

Hello World

1
2
3
4
5
6
7
package main

import "fmt"

func main() {
fmt.Println("Hello, World!")
}

典型的Go文件布局:

  1. package子句
  2. 任何import语句
  3. 实际代码

每个Go文件都必须以package子句开头。

每个Go文件都必须导入它引用的每个包。

Go文件必须只导入它们引用的包。

Go查找名为main的函数并首先运行。

Go中的所有内容都区分大小写。

Println函数是fmt包的一部分,因此Go需要在函数调用之前使用报名。

阅读全文 »

《OpenSceneGraph 3.0 Beginners Guide》 笔记
OSG-3.6.5 + VS2017

Hello World

1
2
3
4
5
6
7
8
9
10
11
12
#include <osgDB/ReadFile>
#include <osgViewer/Viewer>

int main()
{
osg::ref_ptr<osg::Node> root = osgDB::readNodeFile("cessna.osg");

osgViewer::Viewer viewer;
viewer.setSceneData(root.get());

return viewer.run();
}
阅读全文 »

包管理工具Vcpkg 的使用
教程:从清单文件安装依赖项

Linux下开发,用到什么依赖库,直接运行apt install xxx 安装即可,好用到爆炸。Python、Node.js等也都有类似的包管理器。而VS环境下需要自己下载各种依赖库的源码、编译,折腾半天,最后还不一定能用。

而 vcpkg 的诞生,给我们带来了福音。

简介

vcpkg 是 Microsoft 的跨平台开源软件包管理器,极大地简化了 Windows、Linux 和 macOS 上第三方库的配置与安装。如果项目要使用第三方库,建议通过 vcpkg 来安装它们。vcpkg 同时支持开源和专有库。

vcpkg 为我们处理好了各种软件包的依赖关系和编译配置,安装软件包时软件包源码被下载下来,并通过 CMake 在本地编译。目前官方和社区提供了对各种平台和编译器的支持。

安装

1
2
3
git clone https://github.com/microsoft/vcpkg
cd vcpkg
.\bootstrap-vcpkg.bat

经典模式

在经典模式下,使用 vcpkg 作为命令行接口在全局安装目录中安装依赖项。 该目录通常位于 %VCPKG_ROOT%/installed,其中 %VCPKG_ROOT% 是 vcpkg 安装目录所在的位置。

查询软件包:

1
.\vcpkg.exe search xxx

安装软件包:

1
.\vcpkg.exe install xxx

清单模式

清单模式是大多数用户推荐的工作流。

在清单模式下,在名为 vcpkg.json 的清单文件中声明项目的直接依赖项。

清单文件有自己的 vcpkg_installed 目录,可在其中安装依赖项,与所有包都安装在全局 %VCPKG_ROOT%/installed 目录中的经典模式不同。每个项目都可以有自己的清单和自己的一组依赖项,这些依赖项不会与其他项目的依赖项发生冲突。

假设项目需要以下依赖库:cxxopts、fmt、range-v3。

在项目所在的同一目录中创建一个名为 vcpkg.json 的文件:

1
2
3
4
5
6
7
{
"dependencies": [
"cxxopts",
"fmt",
"range-v3"
]
}

如果想要手动安装依赖项,只需在包含清单文件的目录中运行 vcpkg install

该命令完成后,所有生成的包都将出现在 vcpkg_installed 目录中。 此目录的具体位置取决于构建系统;通常,在构建系统的默认输出文件夹内,或 vcpkg.json 文件旁边。

https://flask-restful.readthedocs.io/en/latest/quickstart.html#full-example

A Minimal API

1
2
3
4
5
6
7
8
9
10
11
12
13
14
from flask import Flask
from flask_restful import Resource, Api

app = Flask(__name__)
api = Api(app)

class HelloWorld(Resource):
def get(self):
return {'hello': 'world'}

api.add_resource(HelloWorld, '/')

if __name__ == '__main__':
app.run(debug=True)

运行程序:

1
2
3
$ python api.py
* Running on http://127.0.0.1:5000/
* Restarting with reloader

测试API:

1
2
$ curl http://127.0.0.1:5000/
{"hello": "world"}
阅读全文 »

使用系统环境变量

1
$ENV{PATH}

指定项目名称

相当于VS中的解决方案名称。

1
project(sqlitebrowser)

指定最低支持的CMake版本

1
cmake_minimum_required(VERSION 2.8.7)

设置变量

1
2
3
4
5
6
7
8
9
10
11
set(QSCINTILLA_DIR libs/qscintilla/Qt4Qt5)

set(SQLB_HDR
src/version.h
src/sqlitetypes.h
src/csvparser.h
src/sqlite.h
src/grammar/sqlite3TokenTypes.hpp
src/grammar/Sqlite3Lexer.hpp
src/grammar/Sqlite3Parser.hpp
)

使用变量

1
${SQLB_HDR}

添加一个可执行程序项目

${PROJECT_NAME}指project指令中设置的名称。

1
2
3
4
5
6
7
8
add_executable(${PROJECT_NAME}
${SQLB_HDR}
${SQLB_SRC}
${SQLB_FORM_HDR}
${SQLB_MOC}
${SQLB_RESOURCES_RCC}
${SQLB_MISC}
)

添加预处理器定义

1
2
add_definitions(-DENABLE_SQLCIPHER)
add_definitions(-std=c++11)

if语句

1
2
3
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Release")
endif()
阅读全文 »
0%