Win7 64位 VS2015及MinGW环境编译矢量库agg-2.5和cairo-1.14.6

news2024/11/16 19:31:47

书接上文,昨天装了MinGW,主要原因之一是要用到MSYS,所以顺手把FFMPEG又编译了一遍。

回到主题,其实我是想编译矢量库,因为最近要学习一些计算几何算法,所以找个方便的2D画图库就很重要。

说白了其实是懒得用OpenGL写画几何体代码,画线,AA什么的。

不管怎么说,介绍看的是这篇文章。

C++矢量图形库系列(1)——矢量图形库乱谈(转) - 北山愚公* - 博客园

提到了3个矢量库,因为墙的原因,google的Skia死活弄不下来,所以只写前两个。

首先是AGG,http://www.antigrain.com/

第三方依懒库只有freetype,而freetype自带sln工程,所以编译没有问题,我直接打开的2010工程

freetype2\builds\windows\vc2010

然后新建一个Win32 Console Static library空工程,把AGG源码手动添加进工程,注意平台相关,别把没用的也加进去

并把相关目录加到include目录中,再加上freetype2的include,library,

编译就行了

相关目录

font_freetype

font_win32_tt

gpc

src

src\ctrl

src\platform\win32

========================================

然后新建一个Win32 Project,也就是窗口程序,实际上我建的Win32 Console空工程,然后在工程设置又改成的窗口,怎么弄都行。

配置上AGG的include,library目录

然后使用下面这个测试hello world,原文在哪忘了,只是测试下。

 #include "agg_basics.h"
 #include "agg_rendering_buffer.h"
 #include "agg_rasterizer_scanline_aa.h"
 #include "agg_scanline_u.h"
 #include "agg_renderer_scanline.h"
 #include "agg_pixfmt_rgb.h"
 #include "platform/agg_platform_support.h"
 #include "agg_ellipse.h"
 #include "agg_conv_contour.h"
 #include "agg_conv_stroke.h" 
 
 #include "agg_conv_marker.h"
 #include "agg_arrowhead.h"
 #include "agg_path_storage.h"
 #include "agg_vcgen_markers_term.h"
 
 #include <agg_conv_stroke.h> // conv_stroke
 #include <agg_conv_dash.h> // conv_dash
 #include <agg_conv_marker.h> // conv_marker
 #include <agg_conv_curve.h> // conv_curve
 #include <agg_conv_contour.h> // conv_contour
 #include <agg_conv_smooth_poly1.h> // conv_smooth_poly1.h
 #include <agg_conv_bspline.h> // conv_bspline
 #include <agg_conv_transform.h> // conv_transform
 
 class the_application : public agg::platform_support
 {
 public:
     the_application(agg::pix_format_e format, bool flip_y) :
         agg::platform_support(format, flip_y)
     {
     }
 
     virtual void on_draw()
     {
         //Rendering Buffer              //用于存放像素点阵数据的内存块,这里是最终形成的图像数据
         agg::rendering_buffer &rbuf = rbuf_window();
         agg::pixfmt_bgr24 pixf(rbuf);
 
         // Renderers
         typedef agg::renderer_base<agg::pixfmt_bgr24> renderer_base_type;  //底层渲染器
         renderer_base_type renb(pixf);
 
         // typedef agg::renderer_scanline_aa_solid<renderer_base_type> renderer_scanline_type;   //高层渲染器
         typedef agg::renderer_scanline_bin_solid<renderer_base_type> renderer_scanline_type;   //高层渲染器
 
         renderer_scanline_type rensl(renb);
         /*
         // Vertex Source
         //agg::ellipse ell(100,100,50,50); //顶点源,里面存放了一堆2D顶点以及对应的命令,这个顶点源呈现的是一个圆形
         agg::triangle ell(100,100,50);
 
         // Coordinate conversion pipeline //坐标转换管道,它可以变换Vertex Source中的顶点,比如矩阵变换,轮廓提取,转换为虚线等。
         //typedef agg::conv_contour<agg::ellipse> ell_cc_type;     //扩展轮廓线
         typedef agg::conv_contour<agg::triangle> ell_cc_type;
         ell_cc_type ccell(ell);
 
         typedef agg::conv_stroke<ell_cc_type> ell_cc_cs_type;    //只显示轮廓线
         ell_cc_cs_type csccell(ccell);
         */
 
         // Vertex Source 
 
         agg::ellipse ell(, , , );  // 圆心在中间
                                          // Coordinate conversion pipeline
         agg::trans_affine mtx;        // trans_affine不 仅仅用于源顶点的变换,在AGG库中有不少地方都能看到它
         mtx.scale();             // x轴缩小到原来的一半
         mtx.rotate(agg::deg2rad()); // 旋转30度
         mtx.translate(, ); // 平移100,100
         typedef agg::conv_transform<agg::ellipse> ell_ct_type;
         ell_ct_type ctell(ell, mtx); // 矩阵变换 
 
         typedef agg::conv_contour<ell_ct_type> ell_cc_type;
         ell_cc_type ccell(ctell); // 轮廓变换 
 
         typedef agg::conv_dash<ell_cc_type> ell_cd_type;
         ell_cd_type cdccell(ccell);
         cdccell.add_dash(, );
 
         typedef agg::conv_stroke<ell_cd_type> ell_cc_cs_type;
         // ell_cc_cs_type csccell(ccell); // 转换成多义线
         ell_cc_cs_type csccell(cdccell);
 
         // csccell.width(3);
 
         // Scanline Rasterizer            //把顶点数据(矢量数据)转换成一组水平扫描线,扫描线由一组线段(Span)组成,线段(Span)包含了起始位置、长度和覆盖率(可以理解为透明度)信息。AGG的抗锯齿(Anti-Aliasing)功能也是在这时引入的。
         agg::rasterizer_scanline_aa<> ras;
         agg::scanline_u8 sl;
 
         // Draw
         renb.clear(agg::rgba8(, , ));
         //  renb.clip_box(30,30,160,160); // 设置可写区域 
 
         ; i<; i++)
         {
             ccell.width(i * );
             ras.add_path(csccell);
             rensl.color(agg::rgba8(, , i * ));
             //  agg::render_scanlines(ras,sl,rensl);
             agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(, , i * ));
 
         }
 
         ;
         ++i;
         agg::path_storage ps;
 
         ps.start_new_path();
         ps.move_to(+ i, );
         ps.line_to(, );
         ps.line_to(, );
         ps.end_poly();
 
         agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
         ras.add_path(csps);
         agg::render_scanlines_aa_solid(ras, sl, renb, agg::rgba8(, , ));
 
         /*
         agg::arrowhead ah;
         ah.head(0,10,5,5);
         ah.tail(10,10,5,5);
         // 用path_storage生成一条直线
         agg::path_storage ps;
         ps.move_to(160,60);
         ps.line_to(100,100);
         // 转换
         agg::conv_stroke<agg::path_storage, agg::vcgen_markers_term> csps(ps);
         agg::conv_marker<agg::vcgen_markers_term, agg::arrowhead>
         arrow(csps.markers(), ah);
         // 画线
         ras.add_path(csps);
         agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(0,0,0));
         // 画箭头
         ras.add_path(arrow);
         agg::render_scanlines_aa_solid(ras,sl,renb,agg::rgba8(255,0,0));
 
         agg::triangle t(100,100,50);//自定义顶点源
         agg::conv_smooth_poly1_curve<agg::triangle> cspct(t);
         ras.add_path(cspct);
         agg::render_scanlines_aa_solid(
         ras,sl,renb,agg::rgba8(255,0,0));
 
         for(int j=0; j<20; j++)
         pixf.blend_vline(50+j,20,100,agg::rgba(j/20.0,0,0),128);
 
         agg::int8u* p = rbuf.row_ptr(20);//得到第20行指针
         memset(p,0,rbuf.stride_abs());//整行以0填充
         */
     }
 
     virtual void on_post_draw(void* raw_handler) override
     {
     }
 
 };
 
 int agg_main(int argc, char* argv[])
 {
 
     the_application app(agg::pix_format_bgr24, false);
 
     app.caption("AGG Example. Anti-Aliasing Demo");
 
     , , agg::window_resize))
     {
         return app.run();
     }
     ;
 
 }

编译运行,一切OK的话显示如图

还没完,AGG最叼的是自带演示工程水平非常高,在源码中有一个叫examples的目录,直接拖一个idea.cpp编译,如图

所有例子都有预编译好的二进制版可看,真正良心实用的例子。

http://www.antigrain.com/demo/index.html

好,到此AGG部分就结束了。

========================================

接下来看看Cairo

第三方依懒库有

libpng

zlib

pixman

当然Cairo源码肯定少不了 Download

libpng和zlib编译直接使用之前编译好的 Win7 VS2015环境编译Libpng - KILEYI - 博客园

官网有一个说明,但是我没完全照做。

end to end build for win32

主要不同的是,我的libpng和zlib编译好了,直接从pixman开始的

首先打开VS2015命令行开发环境,在开始菜单中可以找到

然后进入到pixman源码目录

D:\CPPLibs\pixman-0.34.0\pixman

注意这个不是源码根目录,而是pixman目录,一定不能搞错了

然后新建一个setpath.bat文件,内容如下,主要就是设置一下msys的bin到当前环境目录,并且release编译

set PATH=%PATH%;D:\MinGW\msys\1.0\bin
make -f Makefile.win32 "CFG=release"

之后在命令行中运行这个bat,一切OK会在release目录生成pixman-1.lib,等会儿要用到

3个依赖库都搞定后就要编译Cairo了,我的源码目录

D:\CPPLibs\cairo-1.14.6

然后在与源码目录同级新建libpng,zlib,pixman目录,放上对应的lib文件

D:\CPPLibs\libpng\libpng.lib

D:\CPPLibs\zlib\zdll.lib

D:\CPPLibs\pixman\pixman\release\pixman-1.lib

注意有些需要改名

然后回到源码目录

D:\CPPLibs\cairo-1.14.6

新建setpath.bat文件,内容如下,主要是设置include和library路径,出于一些原因我的libpng和zlib的library放到了一起,你如果没放到一起就自己加上

set INCLUDE=%INCLUDE%;D:\CPPLibs\zlib-1.2.8
set INCLUDE=%INCLUDE%;D:\CPPLibs\lpng1621
set INCLUDE=%INCLUDE%;D:\CPPLibs\pixman-0.34.0\pixman
set INCLUDE=%INCLUDE%;D:\CPPLibs\cairo-1.14.6\boilerplate
set INCLUDE=%INCLUDE%;D:\CPPLibs\cairo-1.14.6\src

set LIB=%LIB%;D:\CPPLibs\lpng1621\projects\vstudio\Release

make -f Makefile.win32 "CFG=release"

有人可能想为什么这里都设置好了路径,上面还要建立libpng和zlib,pixman目录,这主要是因为官方那个编译文件默认是写死的,只找他默认改名后的目录和文件,

我懒得改所以就直接复制了一份,在官方的那个编译说明中好像有提到

如果编译完一切OK,你会看到下面几个需要的文件

D:\CPPLibs\cairo-1.14.6\src\release\cairo.lib

D:\CPPLibs\cairo-1.14.6\src\release\cairo-static.lib

D:\CPPLibs\cairo-1.14.6\src\release\cairo.dll

我只需要cairo.lib和cairo.dll

接下来新建Win32 Console空工程,配置好Cario和OpenGL的include和library目录

使用glut,glext,opengl1.x语法,写个简单的测试工程

 #include <stdlib.h>
 #include <stdio.h>
 #include <malloc.h>
 
 #define _USE_MATH_DEFINES
 #include <math.h>
 
 #include <gl/glut.h>
 #include <gl/glext.h>
 
 #include <cairo.h>
 
 ;
 ;
 ;
 ;
 double line_width = 5;
 //double line_width = 1 / win_width;
 
 cairo_surface_t * surf = NULL;
 cairo_t         * cr = NULL;
 unsigned char   * surf_data = NULL;
 
 GLuint texture_id;
 
 // Interface //
 
 void opengl_init(void)
 {
     printf("OpenGL version: %s\n", glGetString(GL_VERSION));
     printf("OpenGL vendor: %s\n", glGetString(GL_VENDOR));
     printf("OpenGL renderer: %s\n", glGetString(GL_RENDERER));
 
     glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
     glDisable(GL_DEPTH_TEST);
     glEnable(GL_BLEND);
     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
     glEnable(GL_TEXTURE_RECTANGLE_ARB);
 }
 
 void opengl_cleanup(void)
 {
     glDeleteTextures(, &texture_id);
 }
 
 void opengl_draw(int width, int height, unsigned char * surf_data)
 {
     if (!surf_data)
     {
         printf("draw_func() - No valid pointer to surface-data passed\n");
         return;
     }
 
     glMatrixMode(GL_MODELVIEW);
     glLoadIdentity();
     glClear(GL_COLOR_BUFFER_BIT);
 
     glPushMatrix();
 
     glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
     glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
         ,
         GL_RGBA,
         width,
         height,
         ,
         GL_BGRA,
         GL_UNSIGNED_BYTE,
         surf_data);
 
     glColor3f(0.25f, 0.5f, 1.0f);
     glBegin(GL_QUADS);
     glTexCoord2f(0.0f, 0.0f);
     glVertex2f(0.0f, 0.0f);
     glTexCoord2f((GLfloat)width, 0.0f);
     glVertex2f(1.0f, 0.0f);
     glTexCoord2f((GLfloat)width, (GLfloat)height);
     glVertex2f(1.0f, 1.0f);
     glTexCoord2f(0.0f, (GLfloat)height);
     glVertex2f(0.0f, 1.0f);
     glEnd();
 
     glPopMatrix();
 }
 
 void opengl_resize(int width, int height)
 {
     glViewport(, , width, height);
     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glOrtho(0.0f, 1.0f, 0.0f, 1.0f, -1.0f, 1.0f);
 
     glClear(GL_COLOR_BUFFER_BIT);
 
     glDeleteTextures(, &texture_id);
     glGenTextures(, &texture_id);
     glBindTexture(GL_TEXTURE_RECTANGLE_ARB, texture_id);
     glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,
         ,
         GL_RGBA,
         width,
         height,
         ,
         GL_BGRA,
         GL_UNSIGNED_BYTE,
         NULL);
     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL);
 }
 
 void drawShape()
 {
     //save current brush
     cairo_save(cr);
 
     // clear background
     cairo_set_operator(cr, CAIRO_OPERATOR_OVER);
     //cairo_scale(cr, (double)win_height / 1.0f, (double)win_height / 1.0f);
     cairo_set_source_rgba(cr, , , , );
     cairo_paint(cr);
 
     //set line color and style
     cairo_set_line_cap(cr, CAIRO_LINE_CAP_ROUND);
     cairo_set_line_width(cr, line_width);
 
     ;
     angle += 0.01f;
 
     //画矩形
     cairo_set_source_rgba(cr, , , , );
     //cairo_rectangle(cr, 0.5f + sinf(angle) * 0.1f, 0.5f, 0.1f, 0.1f);
     cairo_rectangle(cr, hw + sin(angle) * , hh, , );
     cairo_fill(cr);
     cairo_stroke(cr);
 
     //画弧
     cairo_set_source_rgba(cr, , , , );
     cairo_arc(cr, , hh, , ,  * M_PI);
     //cairo_fill(cr);
     cairo_stroke(cr);
 
     //画线
     ;
     ;
     ;
     ;
     ;
 
     x = r * cosf(angle);
     y = r * sinf(angle);
 
     cairo_set_source_rgba(cr, , , , );
     cairo_move_to(cr, x + posx, y + posy);
     cairo_line_to(cr, -x + posx, -y + posy);
     cairo_stroke(cr);
 
     //restore previous brush
     cairo_restore(cr);
 }
 
 void display(void)
 {
     drawShape();
 
     opengl_draw(win_width, win_height, surf_data);
 
     glutSwapBuffers();
 }
 
 cairo_t*
 create_cairo_context(int               width,
     int               height,
     int               channels,
     cairo_surface_t** surf,
     unsigned char**   buffer)
 {
     cairo_t* cr;
 
     // create cairo-surface/context to act as OpenGL-texture source
     *buffer = (unsigned char*)calloc(channels * width * height, sizeof(unsigned char));
     if (!*buffer)
     {
         printf("create_cairo_context() - Couldn't allocate buffer\n");
         return NULL;
     }
 
     *surf = cairo_image_surface_create_for_data(*buffer,
         CAIRO_FORMAT_ARGB32,
         width,
         height,
         channels * width);
     if (cairo_surface_status(*surf) != CAIRO_STATUS_SUCCESS)
     {
         free(*buffer);
         printf("create_cairo_context() - Couldn't create surface\n");
         return NULL;
     }
 
     cr = cairo_create(*surf);
     if (cairo_status(cr) != CAIRO_STATUS_SUCCESS)
     {
         free(*buffer);
         printf("create_cairo_context() - Couldn't create context\n");
         return NULL;
     }
 
     return cr;
 }
 
 void cleanup(void)
 {
     opengl_cleanup();
     free(surf_data);
     cairo_destroy(cr);
     exit();
 }
 
 void keyboard(unsigned char key, int x, int y)
 {
     switch (key)
     {
     //27 is ESC key
     :
     case 'q':
         cleanup();
         break;
 
     case 'd':
         cairo_surface_write_to_png(surf, "frame.png");
         break;
 
     case '+':
         )
             line_width += ;
         break;
 
     case '-':
         )
             line_width -= ;
         break;
 
     }
 }
 
 void idle(void)
 {
     glutPostRedisplay();
 }
 
 int main(int argc, char ** argv)
 {
     glutInit(&argc, argv);
     glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGBA);
     glutInitWindowSize(win_width, win_height);
 
     )
         exit(-);
 
     // create cairo-surface/context to act as OpenGL-texture source
     cr = create_cairo_context(win_width, win_height, , &surf, &surf_data);
 
     // setup "GL-context"
     opengl_init();
 
     glutDisplayFunc(display);
     glutKeyboardFunc(keyboard);
     glutIdleFunc(idle);
     opengl_resize(win_width, win_height);
 
     glutMainLoop();
 
     ;
 }

至此Cairo部分就结束了,活动一下筋骨,可以开始写应用了

 

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

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

相关文章

我把GPT 的学习轨迹可视化了竟和人类十分类似 |ACL2023

回想一下我们小时候是如何习得一门语言的&#xff1f;一般而言&#xff0c;在人类婴儿出生第一年内&#xff0c;最开始婴儿只能模仿式的说出一些“音素”&#xff0c;说出一些最简单与基本的单词或句子&#xff0c;而伴随着成长&#xff0c;在大约一岁到三岁的阶段&#xff0c;…

windows进程结构体

了解进程线程的概念后&#xff0c;我们就来看看windows里面的进程长什么样子的。进程本质上就是一个结构体。在Linux里面也称之为进程描述符。当操作系统创建一个进程的时候&#xff0c;它会填充一个结构体&#xff0c;往这个结构体里写入数据&#xff0c;这个结构体就用于管理…

Queue,List,Deque联系

如图所示&#xff0c;可以得出LinkedList既可以是双向链表也可以是双端队列&#xff0c;Deque接口继承了Queue接口 Queue add(E):boolean 在队尾添加元素&#xff0c;添加成功返回true&#xff0c;如果队列已满无法添加则抛出异常。offer(E):boolean 在队尾添加元素&#xff0…

linux mail -s发送邮件异常解决

异常&#xff1a; Error initializing NSS: Unknown error -8015. "/root/dead.letter" 11/301 . . . message not sent. 出现此问题&#xff0c;大概率是和证书相关。如果没有安装证书&#xff0c;请先安装&#xff1a; 1&#xff0c;下载 yum -y install mailx …

Python采集某xsp内容, m3u8视频内容下载

前言 大家早好、午好、晚好吖 ❤ ~欢迎光临本文章 环境使用: Python 3.8 Pycharm 专业版 模块使用: import requests >>> pip install requests import re 正则表达式 解析数据 import json 基本步骤去实现 一. 数据来源分析 通过开发者工具进行抓包分析, 分…

轻松构建交互式应用程序:探索Gradio Components模块的神奇世界!

❤️觉得内容不错的话&#xff0c;欢迎点赞收藏加关注&#x1f60a;&#x1f60a;&#x1f60a;&#xff0c;后续会继续输入更多优质内容❤️ &#x1f449;有问题欢迎大家加关注私戳或者评论&#xff08;包括但不限于NLP算法相关&#xff0c;linux学习相关&#xff0c;读研读博…

抽头延迟线信道模型

本专栏包含信息论与编码的核心知识&#xff0c;按知识点组织&#xff0c;可作为教学或学习的参考。markdown版本已归档至【Github仓库&#xff1a;https://github.com/timerring/information-theory 】或者公众号【AIShareLab】回复 信息论 获取。 文章目录 时变多径信道的信道…

突破技术边界,开创“粽“享未来

突破技术边界&#xff0c;开创“粽“享未来 端午节的由来端午节的习俗端午祈福 博主 默语带您 Go to New World. ✍ 个人主页—— 默语 的博客&#x1f466;&#x1f3fb; 《java 面试题大全》 &#x1f369;惟余辈才疏学浅&#xff0c;临摹之作或有不妥之处&#xff0c;还请读…

南京阿里云代理商:阿里云服务器的可扩展性和弹性如何?是否支持按需付费?

南京阿里云代理商&#xff1a;阿里云服务器的可扩展性和弹性如何&#xff1f;是否支持按需付费&#xff1f;   一、阿里云服务器的可扩展性   阿里云作为业界知名的云服务提供商&#xff0c;其服务器具有极强的可扩展性。可扩展性主要体现在以下几方面&#xff1a;   1. …

行为型模式--状态模式

目录 举例 状态模式 定义 结构 代码实现 优缺点 优点&#xff1a; 缺点&#xff1a; 使用场景 举例 【例】通过按钮来控制一个电梯的状态&#xff0c;一个电梯有开门状态&#xff0c;关门状态&#xff0c;停止状态&#xff0c;运行状态。每一 种状态改变&#xff0c;都…

Xdebug的安装及使用

Xdebug的安装及使用 前言一、Xdebug如何配置二、PHPstrom配置三、Xdebug的使用1.面板功能解释2.调试功能详解 四、Xdebug原理 前言 软件调试是泛指重现软件缺陷问题,定位和 查找问题根源,最终解决问题的过程,编写的程序不可能一直不出错&#xff0c;所以调试很重要调试通常有如…

西安阿里云代理商:阿里云服务器的可扩展性和弹性如何?是否支持按需付费?

西安阿里云代理商&#xff1a;阿里云服务器的可扩展性和弹性如何&#xff1f;是否支持按需付费&#xff1f;   一、阿里云服务器的可扩展性   阿里云作为业界知名的云服务提供商&#xff0c;其服务器具有极强的可扩展性。可扩展性主要体现在以下几方面&#xff1a;   1. …

小米note3刷机-从miui12刷回miui9

小米note3刷机-从miui12刷回miui9 文章目录 小米note3刷机-从miui12刷回miui9解除BL锁进入开发者模式遇到的问题解决BootLoader无法连接电脑的问题 导包 3月份原本想买一部小米6回来刷机,结果发现小米6的二手价格有一点点high。然后就选了一个 大平版 小米note3 但是直到昨天…

SpringBoot 如何使用 Logback 进行日志记录

SpringBoot 如何使用 Logback 进行日志记录 在开发 Web 应用程序时&#xff0c;日志记录是非常重要的一部分。日志可以帮助我们跟踪应用程序的运行情况&#xff0c;并帮助我们快速地排查问题。在 SpringBoot 中&#xff0c;我们可以使用 Logback 进行日志记录。Logback 是一款…

F407/103MAP文件

认识MAP文件 MDK编译工程&#xff0c;会生成一些中间文件&#xff08;如.o、.axf、.map 等&#xff09;&#xff0c;最终生成hex文件&#xff0c;以便下载到MCU上面执行。这些文件分为 11 个类型&#xff0c;其中4种文件比较重要。 比如&#xff1a; 本文主要讲解map文件。 map…

第四章 死锁

目录 一、死锁的概念 1.1 什么是死锁 1.2 死锁、饥饿、死循环的区别 1.2.1 死锁 1.2.2 饥饿 1.2.3 死循环 1.2.4 三者间的异同 1.3 死锁产生的必要条件 1.3.1 互斥条件 1.3.2 不剥夺条件 1.3.3 请求和保持条件 1.3.4 循环等待条件 1.4 什么时候会发生死锁 1.5 …

深入理解Java中的synchronized

文章目录 前言正文一、多线程操作同一数据时的问题二、问题分析三、synchronized 解决问题四、synchronized 是怎么解决问题的五、Java1.6时的优化5.1 自旋锁5.2 自适应锁5.3 锁消除5.4 锁粗化5.5 偏向锁&#xff08;单线程高效场景&#xff09;5.2 轻量级锁&#xff08;多线程…

MySQL数据表查询

&#x1f607;作者介绍&#xff1a;一个有梦想、有理想、有目标的&#xff0c;且渴望能够学有所成的追梦人。 &#x1f386;学习格言&#xff1a;不读书的人,思想就会停止。——狄德罗 ⛪️个人主页&#xff1a;进入博主主页 &#x1f5fc;专栏系列&#xff1a;进入MySQL知识专…

IO、存储、文件系统的简单介绍

目录 一.什么是IO 第一类:存储器IO 第二类:设备IO 二.存储 三:文件系统 总结 一.什么是IO I(input):放入数据 O(output):取出数据 所以我们平时说的IO,实际上就是放入数据和存储数据的意思 在这里,我们一般将IO又分为两大类 第一类:存储器IO 这类IO主要针对的是计算机中…

2023年最新同步网盘排行榜,了解哪些平台适合您的文件同步需求!

在数码领域&#xff0c;同步盘是一个极其受欢迎的工具&#xff0c;它可以帮助人们在不同设备之间共享文件。作为同步盘用户&#xff0c;我们关心的一个很重要的问题就是&#xff0c;在同步盘市场上&#xff0c;哪些同步盘是最好的&#xff1f; 今天我们综合了不同的产品测评网站…