欢迎来到皮皮网网站!

【直播APP源码代搭建】【飞q源码】【赛马游戏源码】cli源码 c

时间:2024-12-26 03:34:38 来源:稳坐钓鱼台指标源码

1.一文秒懂cli、snmp、yang、netconf、restconf、openconfig
2.一次vue-cli4项目升级到vite的直播APP源码代搭建经历
3.几种编程语言的简单理解
4.环氯茚酸简介
5.如何编译SQLite-How To Compile SQLite
6.数据库中间件-cetus源码介绍

cli源码 c

一文秒懂cli、snmp、yang、netconf、restconf、openconfig

       前言

       随着网络技术的不断进步,CLI、SNMP、NETCONF、RESTCONF、OPENCONFIG等网络管理技术应运而生,以满足不同场景下的管理需求。本文将总结这些技术的特点与应用场景。

       CLI

       CLI(命令行界面)自网络诞生以来,就是网络管理的基础。它提供简单且功能完备的界面,易于上手。然而,随着设备数量的增加,CLI的管理效率逐渐降低,自动化需求日益迫切。

       SNMP

       SNMP(简单网络管理协议)简化了网络设备的监控与管理,通过C/S架构实现设备与管理系统的交互。SNMP提供了三个版本,适用于数据采集和设备监控。虽然简单易用,但存在数据交互效率低和缺乏事务支持等问题。

       NETCONF

       NETCONF(网络配置协议)与RESTCONF等技术基于XML和HTTP协议,为设备配置提供了更高效和灵活的接口。NETCONF支持XML数据格式传输,具备配置、订阅等功能,但相较于RESTCONF在数据交互效率上有所不足。

       RESTCONF

       RESTCONF是NETCONF与HTTP协议的结合,以JSON格式提供高效的数据交互接口,简化了Web应用访问设备的需求。RESTCONF在性能和开发效率上优于NETCONF,飞q源码成为现代网络设备管理的优选方案。

       OPENCONFIG

       面对不同厂商设备之间的互操作性问题,OPENCONFIG提出了一套与厂商无关的模型驱动网络管理方案。它通过通用数据模型、流式数据遥测、管理协议和测试合规性,实现了网络配置与监控的标准化,促进了设备间的兼容性和互操作性。

       gNMI

       gNMI(gRPC网络管理接口)作为一套基于gRPC的标准化网络管理接口,简化了设备间的数据交互,提高了性能和效率。gNMI提供了一套标准化的API,为设备管理和监控提供了强大的支持。

       总结

       CLI、SNMP、NETCONF、RESTCONF、OPENCONFIG等技术各具特色,适用于不同场景下的网络管理需求。技术选型应根据实际场景和需求选择最合适的方案。每项技术的诞生和发展都为网络管理带来了便利,它们都是网络技术发展的重要里程碑。

一次vue-cli4项目升级到vite的经历

       背景

       使用vue-cli4的项目,业务写多了之后开发运行和打包都慢了很多,为了提升开发体验以及更新团队技术框架,需要升级到更高级的脚手架上,两种方案:一是升级到vue-cli5,二是升级到最新的vite。

       其中第一种方案升级简单,经过实验,打包的速度不升反慢,这可能和项目中的有依赖以及业务代码有关。

       第二种方案升级vite,经过可行性调查,升级到vite的成功率非常高,最后决定从vue-cli4升级到vite,这是一个高风险高回报的事情,因为尽管市面上已存在很多升级成功的案列,但是每个项目都不一样,我们的项目也很庞大,依赖很多,赛马游戏源码并没有%升级成功的把握。而升级成功的回报也很显而易见,开发环境几乎秒运行,开发体验得到了显著提升。

升级前后对比

       ||vue-cli4|vite||---|---|---||开发启动时间|ms|ms||生产打包时间|s|s||打包体积|.6MB|.6MB||运行期间同一代码改动编译时间|ms|瞬时|

       生产环境打包时间可能和我们项目中用到了太多vite插件有关系,但开发环境的提升非常显著。

项目状况

       项目中用到的Vue2,VueCli版本:4.5.,版本更新时间为.5.8,vueCli4的最后版本为4.5.(.3.),依赖的webpack版本为^4.0.0

       组件库使用vant,依赖Less预处理器,通过vue.config.js配置设置了less主题色,在webpack仅支持less-loader@5版本以及对应的less版本

       业务css预处理器为stylus:"^0..5",对应stylus-loader:"^3.0.2"

       进行了多页打包(MPA)

       使用了workbox-webpack-plugin插件配置了PWA:WorkboxWebpackPlugin

       配置了多个路径映射(alias别名)

       指定了文件输出路径以及hash配置

       生产环境下关闭productionSourceMap以及css的sourceMap提升打包速度

       proxy开启多个代理

       用到了.env文件中的环境变量

       按照开发规范忽略部分文件后缀以及index.js

       移除了preload脚本

期望结果

       可以使用vite进行开发和打包

       仍保留webpack打包功能(因为项目太大,不能保证升级到vite后会不会有问题,所以仍希望webpack原本功能正常运行)

准备工作

       升级Node版本,vite只支持node及以上,建议升级到v以上。

       安装pnpm工具,pnpm作为更好的npm依赖管理工具,是目前npm和yarn的最好替代品,且有些依赖包使用npm安装时会有异常,使用pnpm安装可解决:pnpm

       小项目尝试一键转换升级:wp2vite、webpack-to-vite,这两个工具都提供了一键将webpack项目转成vite的能力,但对于大中型项目,并不可靠。

开始行动1.安装必要依赖pnpm?add?vite-plugin-env-compatible?vite-plugin-html?vite?vite-plugin-vue2?--dev

       vite-plugin-vue2是处理vue2版本代码的插件,如果项目中是vue3,安装的依赖有所不同,请参考webpack-to-vite

2.复制html到根目录,并修改 注意是复制,并只改动复制后的html,这样才不会破坏原有webpack功能。

       修改复制后的html,增加对应的js文件引用,注意type属性不能少!

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>

       多页打包(MPA),其他页面的html同样操作,不同html引入对应的乐外卖 源码js即可。

3.新增vite.config.js文件,开始迁移最重要的配置部分

       空配置如下:

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })4.修改环境变量

       环境变量主要面临两个问题:

       要兼容webpack和vite的环境变量用法

       解决方法:使用vite插件vite-plugin-env-compatible,让vite中可以使用webpack中读取环境变量的方式,再配合envPrefix配置,让vite可以读取到VUE_APP_开头的环境变量:

?pnpm?add?vite-plugin-env-compatible?-D?import?{ ?defineConfig?}?from?'vite'?import?envCompatible?from?'vite-plugin-env-compatible'?export?default?defineConfig({ plugins:?[?envCompatible()],envPrefix:?['VUE_APP_']?//?很重要?})?//?mian.js测试?console.log(process.env.VUE_APP_UNION_STATS)?console.log(import.meta.env.VUE_APP_UNION_STATS)

       两个打印都得到了正确的结果,注意:vite中默认只能读取到VITE_开头的环境变量,如果不配置envPrefix,则会导致第二个打印为undefind。

       vite.config.js中不能读取到环境变量

       vite.config.js是无法直接通过import.meta.env和process.env获取环境变量的,我们需要通过vite的loadEnv获取。

       我们需要将vite.config.js的导出对象改为函数:

?import?{ ?defineConfig,loadEnv?}?from?'vite'?export?default?({ ?mode?})?=>?{ ?const?isPro?=?mode?===?'production'?//?我们可以通过mode直接判断当前是不是生产环境,注意mode可以在运行指令中指定:`vite?build?--mode?master`,如果没有指定,那默认打包就是production?function?getEnv(key)?{ ?//?定义获取环境变量的方法?return?loadEnv(mode,?process.cwd(),'')[key]?//?第三个参数非常重要,下面有详解?}?return?defineConfig({ ?base:?getEnv('VUE_APP_PUBLICPATH'),?//?读取环境变量?//?...忽略其他代码?})?})

       loadEnv有三个参数,前两个参数基本固定不变,而第三个参数默认情况下是不需要传的,只有在配置了envPrefix项,读取非VITE_开头的变量时才需要,在loadEnv源码中我们可以看到,第三个参数是prefixes:string|string[]='VITE_',也就是环境变量的前缀,默认是VITE_。

       如果你的项目和我一样,读取了VUE_APP_PUBLICPATH这样非VITE_开头环境变量,就在loadEnv的第三个参数传递空字符串即可,这样就能读取到所有的环境变量了。

5.兼容commonjs代码

       项目中有用到commonjs规范的依赖,比如letmd5=require('js-md5').create(),webpack是基于node开发的,支持require语法,在打包的时候webpack也会正确处理这部分代码,但在vite中不会,所以需要将这部分代码改成importmd5from'js-md5'

       项目开发环境下,一些node_modules中的包也会存在commonjs的代码,我们可以通过vite的插件?vite-plugin-commonjs来实现这部分代码的转化,保证开发环境的正常运行。

pnpm?add?@originjs/vite-plugin-commonjs?--dev//?vite.config.js?忽略其他代码import?{ ?viteCommonjs?}?from?'@originjs/vite-plugin-commonjs'export?default?({ ?mode?})?=>?{ return?defineConfig({ plugins:?[//?...viteCommonjs()?//?兼容vite中的cjs导入语法]})})6.解决css预处理的问题

       vite内置了对主流css预处理器的支持(sass/less/stylus),项目使用预处理器时,只需要安装对应预处理依赖即可:

#?.scss?and?.sasspnpm?add?sass?-D#?.lesspnpm?add?stylus?-D#?.styl?and?.styluspnpm?add?stylus?-D

       比较巧的是,我们项目中用到的淘宝搜索源码Stylus的@import别名的语法和vite冲突,@import'~@/public/stylus/mixins'这样的代码是会报错,一开始我找到了插件,可以帮助我们解决这个问题:vite-plugin-stylus-alias,但是都后面打包的时候发现这个插件有副作用,后面采取了其他方法解决。

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>0<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>1

       使用这个插件会导致无法生成sourcemap文件,在打包的时候可以看到警告:Sourcemapislikelytobeincorrect:aplugin(vite-plugin-stylus-alias)wasusedtotransformfiles,butdidn'tgenerateasourcemapforthetransformation.Consulttheplugindocumentationforhelp,鉴于插件作者已经很久没有更新,建议能改成相对路径还是直接改,如果引用地方较多,可以定义文件为全局styl文件最新解决方案:一般出现这个报错是因为插件使用了vite的transformapi转换代码,但是return值缺失导致,解决方法:复制插件代码到项目中,在插件transform函数return的结果中,返回map:null,然后再vite.config.js中引用项目中修改后的插件,即可完美解决,如下:文末解决bug有细说

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>2

       定义stylus全局文件

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>3

       这里需要注意,官方文档中css-preprocessoroptions写的是使用文件名拓展名作为key,stylus的文件拓展名是styl,但是我使用了stylus作为key并不会有问题,相反使用styl作为key则不生效了,后续这个地方可以留意一下。

       在vite源码中,stylus和styl都进行了判断,理论上都可以使用,但目前测试的结果就是styl作为key不生效,可能源码中其他地方还能找到原因。

7.组件库按需导入和定制主题

       我们项目中用到的组件库是Vant2,该组件库依赖Less,以及通过配置文件来定制组件的主题,在配置中我们需要进行修改:

       vue-cli中的主题配置部分如下:

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>4

       vite中主题配置部分如下:

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>5

       按需导入项目中按需导入vant组件库,组件可以成功导入,但是组件的样式缺失了,这是因为在webpack中,babel-plugin-import插件帮我们实现了组件的样式导入,在vite中使用?vite-plugin-style-import插件帮我们实现这个功能,不仅vant组件库,其他诸如element、antv等组件库也可以使用这个插件进行按需导入:

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>6<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>.修改alias别名配置,以及忽略文件后缀

       vite配置别名的方法和vue-cli有所不同,且没有默认的别名,都需要通过配置实现,且vite默认不能忽略文件后缀导入,我们也需要通过修改配置来实现:

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>8

       需要注意extensions配置的顺序,从左到右进行匹配,如果存在同名但类型不同的文件,很可能得到期望外的结果,比如同目录下存在index.js和index.vue,按上面的顺序,import'./index?会优先匹配到index.js文件。这种情况建议补全后缀进行导入。

9.配置前端跨域

       vite配置跨域和webpack也有出入,需要修改配置

<!--?忽略一些代码?--><body><div?id="app"></div>++?<script?type="module"?src="/src/main.js"></script>?++</body>9

       以上就是几种常见的跨域配置方式,webpack中的devServer改为了server,webpack的proxy中的pathRewrite改成了rewrite,并且类型成为了函数,在函数中返回请求的路径即可。

.多页打包以及打包的其他配置

       vite在build.rollupOptions配置多页打包,参考rollupOptions,其他配置参考文档

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).配置运行路径

       base是指项目运行在服务器的哪个路径下,一般通过从环境变量中动态获取。

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).配置EsLint

       vite中使用vite-plugin-eslint插件实现eslint的检查功能,安装过程中发现vite-plugin-eslint@1.4.0会报错,安装1.3.0版本即可。

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })2import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).使用插件@vitejs/plugin-legacy兼容低版本浏览器

       plugin-legacy文档

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ }).配置运行指令import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })5

       可以在指令中声明mode环境,这个mode在vite.config.js中可以得到,具体可以参考前面4.修改环境变量

       保存运行指令npmrunserve开发环境已经可以跑起来了,但是vite的特性是你用到的页面才会进行打包,其他页面没有进行访问,是不会打包的,所以需要进行打包才能知道其他地方改造会不会有问题,打包如果有报错,再解决报错即可。

.解决报错

       globalisnotdefined

       这个错误是在node_modules/buffer/index.js?v=ea7文件中抛出的,我查看了yarn.lock文件,依赖路径为多个vue-cli插件>webpack@4.0.0>node-libs-browser?>buffer

       这个是依赖的问题,第一删除node_modules重新安装依赖。第二更换npm工具为pnpm重装依赖,如果仍不行,建议不建议webpack,删除掉webpack相关依赖。

       网上还有一种做法是:在window对象上挂载global对象,可作为备选方案。

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })6

       @import'~@vant/icons/src/encode-woff2.less';报错

       这个错误是vant组件库中的icon组件抛出的,vite默认不能使用别名,我们在前面配置了别名,但是配置的是~@指向项目中的src目录,这样vant组件库的这个文件引用就找不到了。

       issuesvant

       解决方法:针对vant的这个文件,做一个别名,放到第一位,优先进行匹配:

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })7

       运行vitebuild,css产生了一些警告。

       警告分为两种,一是css中的属性拼写错误,诸如:color写成了colo,background写成了backgrounc,属于语法错误,根据警告提示搜索对应样式进行修改即可。

       二是一些语法正确,但还不清楚为什么压缩时提示了警告:比如stylus修改scoped样式用的>>>语法,以及background?rgba(0,0,0,0.5)提示Unexpected"rgba("。

       Thepackagemayhaveincorrectmain/module/exportsspecifiedinitspackage.json

       这个错误是通过npminstall后运行vite指令报错的,用yarn安装一直很正常,原因是node_modules的某个包的package.json定义的main入口路径错了,所以找不到模块导入。

       解决方法:针对这个模块,定义别名,指向正确的入口:

import?{ ?defineConfig?}?from?'vite'export?default?defineConfig({ })8

       打包后导入函数定义别名后,调用函数报错

       import*asminByfrom'lodash.minby'代码报错了,而且只有在生产环境下才产生。

       解决方法:暂时去掉别名,这应该和lodash的导出方式modules.export在vite中转化成ES语法的过程有关系。

       importminByfrom'lodash.minby'

       requireisnotdefine,通过require导入资源报错

       前面在步骤5已经用了插件vite-plugin-commonjs转化common.js的代码了,require理应不会报错。

       但是require导入资源算是webpack的功能,和js代码不一样,所以导入资源的代码都要进行修改:

       require('./images/logo.png')改成importlogofrom'./images/logo.png'

       这样的修改可以兼容webpack和vite,这是在现有项目中,改动的地方会达到上百处,非常麻烦。

几种编程语言的简单理解

       ä¸‹é¢å…ˆåˆ†åˆ«ç®€ä»‹ä¸‹ã€‚.Net.Net框架是Windows研发出来的跨语言解决方案。它的核心是CLR(公共语言运行库),这是微软发布的CLI(公共语言基础结构)规范的一个实现。CLI分为两部分,一个是CIL(公共中间语言),另一个是CTS(公共类型系统)。可以想象,基于公共类型系统,.net就可以把其下的各种语言中的数据类型翻译为公共数据类型,再将其翻译为公共中间语言,就可以实现跨语言的互通。本来程序就基本等于数据+流程逻辑,两部分都使用了公共规范进行约束后,实现互通性就有可能了。这也是契约式编程的一种思想体现吧。.Net框架下的语言,在生成时,编译器将其翻译为中间语言,在执行前即时编译(即JIT方式)调入内存并运行。此外,.Net的运行时环境与Java虚拟机还是比较相像的,都是基于堆的内存管理机制,托管模式下没有C风格指针(非托管代码可以使用);都有类型系统,.Net称为元数据,Java就是一系列的Class类型的对象实例。这样的结构使其很方便能够支持反射这样的机制,使程序可编程灵活性有很大提高。JavaJava是目前最流行的语言之一,它的优点就是跨平台和移动性。它是基于Java虚拟机的架构,Java源程序被翻译为.class文件的字节码,Java虚拟机接受这些字节码流,解析并生成相应的类型数据并从main方法开始运行。至于源代码的连接加载等操作完全交给虚拟机去处理。Java和.Net很像,按语言来说,Java和C#的语法结构就很像,而C#又是.Net下最有方便的语言。只不过.Net主要还是基于Windows的实现,而Java虚拟机有多个操作系统的实现。前者关注点在跨语言,后者关注点在于跨平台。PythonPython是一种相当年轻的语言,它发展的很快,用户量不断增多。这种语言给我的印象就是对编码风格要求很高(原本就是靠缩进来约束程序块的)。这样坏处就是写代码就得格外小心,好处就是写出来的代码普遍风格较好,易于理解。有强大的代码库可以使用,支持很多上层语言的特性。目前似乎作为脚本语言使用的较多(经常看有人用它和Perl比),但本身是一种通用型的语言,也可以支持图形开发。它的运行原理与Java大致相同,也有虚拟机,执行时将源码翻译为中间语言,再加载到虚拟机上去执行。Python可以支持源码直接运行,但其背后仍然是先执行了将源码转换到中间代码的过程,然后再解释执行。当然为了效率,也可以将源码事先翻译为.pyc字节码文件,再解释执行(这就和Java比较像了)。和Java相比,我认为Python的优势在于它的易用性,代码写出来很简洁,支持高端特性,动态类型,作为上层语言是个很不错的选择。简单理解就是简单理解,现在主要关注点就在这里。以后有机会的话,再深入一些细节吧。

环氯茚酸简介

       环氯茚酸是一种具有药理活性的药物,其主要功效在于解热、镇痛和抗炎,其作用机制是通过抑制前列腺素的合成。它适用于多种关节炎症的治疗,包括变形性关节炎、肩关节炎和颈肩腕综合征,以及腰痛的缓解。

       对于使用方法,一般推荐成人每日服用至毫克,最好将其分为2到3次,且需在饭后服用以提高吸收效果。但需注意的是,环氯茚酸并非适合所有人,部分患者可能出现副作用,如浮肿、血尿素氮水平上升、蛋白尿、粒细胞减少以及皮疹等。因此,消化道溃疡、肝肾疾病患者以及对阿司匹林类药物过敏者应避免使用。

       在使用时,必须遵守医生的建议,切勿与消炎镇痛药物同时服用,以防止可能的药物相互作用。环氯茚酸的常见制剂为片剂,每片剂量为毫克。它的通用名称为环氯茚酸,英文名为Clidanac,还有其他中文别名克力丹酸,以及英文别名Britai和Indanal。

如何编译SQLite-How To Compile SQLite

       SQLite是ANSI-C的源代码。在使用之前必须要编译成机器码。这篇文章是用于各种编译SQLite方法的指南。

       è¿™ç¯‡æ–‡ç« ä¸åŒ…含编译SQLite的每个步骤的反馈,那样可能会困难因为每种开发场景都不同。所以这篇文章描述和阐述了编译Sqlite的原则。典型的编译命令已经作为例子提供了,以期望应用开发者能够使用这些例子作为完成他们自己定制的编译过程的的一个指南。换句话说,这篇文章提供了想法和见解,而不是交钥匙的解决方法。

       èžåˆVS单独源文件

       Sqlite是由超过一百个c源码文件以及众多的目录下的脚本构建的。Sqlite的实现是纯粹的ANSI-C,但是许多C语言源代码文件是由辅助的C程序生成或者转换来的,并且AWK,SED和TCL脚本会融合到完成的sqlite库中。对Sqlite构建需要的C程序和转换和创建C语言源码是一个复杂的过程。

       ä¸ºäº†ç®€åŒ–这些,sqlite也通过一个预打包的合并后的源码文件:sqlite3.c。这个合并文件是一个ANSI-C源码实现整个SQLite库的唯一文件。合并后的文件更容易处理。所有的东西都包含在这一个文件里,所以很容易进入一个更大的C或者C++程序的源码树。所有的代码生成和转换步骤都已经实现了,因此没有辅助的C程序需要去配置和变异,也没有脚本需要去运行。并且,因此所有哭都包含在一个翻译单元,编译器可以做更多高级的优化从而提升5%到%的性能。因为这些原因,融合后的源码文件sqlite3.c对所有程序来讲都是值得推荐的。

       æŽ¨èæ‰€æœ‰çš„应用程序使用融合文件。

       ç›´æŽ¥ä»Žå•ç‹¬çš„源码文件中构建sqlite当然可以,但是并不推荐。对一些特殊的应用程序,可能需要修改构建程序去处理使用那些从网站上下载的预构建的源码文件不能完成的情况。对于这些情况,推荐构建和使用一个定制过的合并文件。换句话说,即使一个工程需要以单独的源码文件构建sqlite,仍然推荐使用一个融合后的源码文件作为一个中间步骤。

       ç¼–译命令行接口(CLI)

       æž„建命令行接口需要三个源码文件:

       sqlite3.c:Sqlite融合的源码文件

       sqlite3.h:匹配sqlite3.c以及定义sqlite的c语言接口的头文件

       shell.c:命令行接口程序本身。这个c源码文件包含一个main()的例程和每轮循环的用户输入的提示符并将输入传给sqlite数据库引擎用于处理。

       æ‰€æœ‰çš„上述源码的三个文件都被包含在下载页面的amalgamation tarball中。

       ä¸ºäº†æž„建CLI,简单的将这三个文件放置在相同的目录下然后一起编译他们。用MSVC:

       cl shell.c sqlite3.c -Fesqlite3.exe

       åœ¨unix系统上(或者在windows上用cygwin或者mingw+msys)典型的命令会有些像这样:

       gcc shell.c sqlite3.c -lpthread -ldl

       ä¸ºäº†SQLite线程安全,需要pthreads库。但是因为CLI是一个单线程的,我们可以指示SQLite构建一个非线程安全的库并因此护绿pthreads库:

       gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl

       -ldl库是在支持动态装载时需要,例如sqlite3_load_extension() 接口和load_extension()

        SQL function。如果这些特性都不要求,那么我们也可以使用SQLITE_OMIT_LOAD_EXTENSION编译时间选项忽略他们。

       gcc -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c

       æœ‰äººå¯èƒ½æƒ³è¦æä¾›å…¶ä»–的编译时间选项(compile-time options),例如SQLITE_ENABLE_FTS3去全文本搜索或者SQLITE_ENABLE_RTREE用于R*树搜索引擎扩展。而有人将正常指定一些编译优化开关。(预编译的CLI可以从选择sqlite网站上使用“-Os”下载下来)有无数种可能的变数在这里。

       å…³é”®ç‚¹åœ¨è¿™é‡Œï¼šæž„建CLI需要编译一起两个C语言文件。shell.c文件包含入口的定义和用户输入的loop,而sqlite融合文件sqlite3.c包含完整的sqlite库的实现。

       ç¼–译TCL接口

        sqlite的tcl接口是一个小的模块被添加到一般的融合文件中。结果是一个新的融合后的源码文件,称之为“tclsqlite3.c”。这个源码文件是生成一个可以使用TCL

       load命令去加载到一个标准的tclsh或者wish中,或者随着sqlite构建成功生成一个单独唯一的tclsh的共享库所需要的。一个tcl的融合的副本被包含在下载页的TEA

        tarball中作为一个文件。

       ä¸ºäº†ç”Ÿæˆä¸€ä¸ªlinux上的sqlite的TCL-loadable库,下面的命令需要满足:

       gcc -o libtclsqlite3.so -shared tclsqlite3.c -lpthread -ldl -ltcl

       ä¸å¹¸çš„是构建Mac OS X 和 Windows的共享库并不是如此简单。对于这些平台最好使用包含在TEA tarball中的configure脚本和makefile.

       ä¸ºäº†ç”Ÿæˆä¸€ä¸ªå•ç‹¬çš„tclsh,可以用于sqlite静态链接,使用如下的编译器调用:

       gcc -DTCLSH=1 tclsqlite3.c -ltcl -lpthread -ldl -lz -lm

       è¿™é‡Œçš„技巧是-DTCLSH=1选项。sqlite的TCL接口模块包含一个main的过程,用于初始化一个TCL解释器并在以-DTCLSH=1编译后进入到一个命令行loop。上述命令可以工作在Linux和Mac

        OS X,虽然有时可能需要依赖于平台调整库选项以及编译的TCL的哪一个版本。

       æž„建融合文件

       ä¸‹è½½é¡µæä¾›çš„sqlite融合文件的版本对大多数用户来说是足够的。然而,一些工程可能想要或者需要构建他们自己的融合文件。一个常见的构建一个定制的融合文件的理由是为了使用特定的compile-time options来定制sqlite库。回想sqlite融合文件中包含了许多C代码由辅助程序和脚本生成。许多的编译时间选项影响这一成圣代码而且必须在融合文件组装前提供给代码生成器。这一系列必须传给代码生成器的编译时间相关的选项会使得sqlite的发布版本各不相同,但是在写这边文章的时候,代码生成器需要知道的这组选项包括:

       SQLITE_ENABLE_UPDATE_DELETE_LIMIT

       SQLITE_OMIT_ALTERTABLE

       SQLITE_OMIT_ANALYZE

       SQLITE_OMIT_ATTACH

       SQLITE_OMIT_AUTOINCREMENT

       SQLITE_OMIT_CAST

       SQLITE_OMIT_COMPOUND_SELECT

       SQLITE_OMIT_EXPLAIN

       SQLITE_OMIT_FOREIGN_KEY

       SQLITE_OMIT_PRAGMA

       SQLITE_OMIT_REINDEX

       SQLITE_OMIT_SUBQUERY

       SQLITE_OMIT_TEMPDB

       SQLITE_OMIT_TRIGGER

       SQLITE_OMIT_VACUUM

       SQLITE_OMIT_VIEW

       SQLITE_OMIT_VIRTUALTABLE

       ä¸ºäº†æž„建一个定制的融合文件,先下载原始的独立源码文件到一个unix或者类unix开发平台。确定获取的原始源码文件不是“预编译过的源文件”。任何人都可以通过到下载页或者直接从configuration management system.获取完整的一套原始源码文件。

       å‡è®¾sqlite源码树被存在一个名为“sqlite”的目录下。计划构建一个平行目录下的名为“bld”的融合文件。首先通过运行sqlite源码树种的configure脚本运行或者通过制作一份源码树顶层的的makfile模板的一份,来构建一个合适的makefile.然后手动编辑这个Makfile去包含需要的编译时间相关的选项。最终运行:

       make sqlite3.c

       åœ¨windows上使用MSVC:

       nmake /f Makefile.msc sqlite3.c

       sqlite3.c的make

       target会自动构造一般的“sqlite3.c”合并的源码文件,以及它的头文件“sqlite3.h”,和包含TCL接口的融合源码文件“tclsqlite3.c”。之后,需要的文件可以被拷贝到文件目录下然后根据上述勾勒的过程编译。

       æž„建一个windows的动态链接库DLL

       ä¸ºäº†åœ¨windows构建一个sqlite的dll使用,首先获取对应的融合过的源码文件,sqlit3.c和sqlite.h。这些可以从SQLite website上下载或者和上述告知的一样去定制生成。

       ä½¿ç”¨å·¥ä½œç›®å½•ä¸‹çš„源码文件,一个dll可以在msvc中使用如下命令生成:

       cl sqlite3.c -link -dll -out:sqlite3.dll

       ä¸Šè¿°å‘½ä»¤éœ€è¦è¿è¡Œåœ¨msvc的MSVC Native Tools Command

       Prompt.如何你已经在机器上安装了msvc,你可能有多个版本的这种命令提示符,针对于x和x的自带构建的,或者交叉编译到ARM的。依赖要求的DLL去使用对应合适的命令提示符工具。

       å¦‚果使用MinGW编译器,命令是这样的:

       gcc -shared sqlite3.c -o sqlite3.dll

       æ³¨æ„MinGW只生成位的dll。另有一个分开的MinGW工程可以用来生成位的dll。可以推断其命令行语法是类似的。需要注意的是最近的MSVC的版本生成的DLLs可能不能工作到WinXP或者更早版本的windows上。因此为了最大限度的兼容你的生成的dll,推荐MinGW。一个好的经验法则是使用MinGW去生成位的dlls,使用msvc去生成位的dlls。

数据库中间件-cetus源码介绍

       数据库中间件Cetus的源码介绍将重点放在其内部流程的解析上。从启动开始,Cetus的执行流程主要从src/mysql-proxy-cli.c文件的main函数出发,调用main_cmdline函数。在正常情况下,启动service后,流程会进入main_cmdline函数中的chassis_mainloop。

       chassis_mainloop函数将调用cetus_master_process_cycle,该过程一直传递chassis结构,其包含关键元素。在cetus_master_process_cycle中,程序开启worker_process,主要在cetus_spawn_process函数中进行,之后进入cetus_worker_process_cycle进行初始化。

       worker_process通过死循环调用主进程chassis_event_loop,并监听客户端消息。在执行流程中,会经过event_base_loop和ev_run等函数,进一步处理事件。

       具体任务处理流程从event_base_loop开始,调用ev_run、ev_invoke_pending、ev_x_cb_io、ev_x_cb,最终到达network_mysqld_con_handle处理传入的SQL语句,并将它们赋值给con->orig_sql。接下来调用normal_read_query_result函数,此函数调用network_mysqld_read_rw_resp处理与后端数据库的消息,并基于返回结果进行后续操作。

       总结,Cetus源码中,从启动至执行流程,再到任务处理,构成了一个完整的数据库中间件执行逻辑。其核心在于通过一系列函数调用,实现消息的传递、处理和最终反馈,确保数据的高效、准确处理。流程清晰,结构严谨,体现了Cetus在数据库中间件领域的专业性和高效性。

wpa_supplicant-2.源码分析

       本文将深入剖析wpa_supplicant-2.源码,重点关注其关键函数在实现Station & P2P模式中的作用。首先,在wpa_supplicant/main.c的主函数main()中,程序主要负责四大任务:

       解析命令行输入的参数,这是初始化过程中的重要步骤。

       调用wpa_supplicant_init()函数,启动wpa_supplicant的核心功能,进行初始化配置。

       紧接着,wpa_supplicant_add_iface()函数被调用,这一步用于增加网络接口,以支持连接不同的网络。

       最后,wpa_supplicant_run()函数被调用,使wpa_supplicant进入运行状态,开始监听和管理无线网络连接。

       值得注意的是,wpa_supplicant的后台服务是wpa_cli命令使用的前提,只有当wpa_supplicant在后台运行时,用户才能通过wpa_cli命令进行配置和管理。具体到wpa_cli命令的下发,其背后的执行逻辑是调用wpa_ctrl_request函数来触发相应的操作。

       通过这段代码的解读,我们可以更直观地理解wpa_supplicant在无线网络管理中的工作流程和关键函数交互。

CListCList类的成员

       CList类的成员提供了对有序列表的多种操作,以下是对这些成员功能的描述:

       构造函数CList:用于创建一个空的有序列表。

       访问头部元素:

       GetHead():返回列表的头部元素。该元素不能为空。

       访问尾部元素:

       GetTail():返回列表的尾部元素。该元素不能为空。

       移除头部元素:

       RemoveHead():从列表头部移除元素。

       移除尾部元素:

       RemoveTail():从列表尾部移除元素。

       添加头部元素:

       AddHead():将一个元素或另一个列表的所有元素添加到头部,生成新的头部。

       添加尾部元素:

       AddTail():将一个元素或另一个列表的所有元素添加到尾部,生成新的尾部。

       移除所有元素:

       RemoveAll():从列表中移除所有元素。

       获取元素位置:

       GetHeadPosition():返回头部元素的位置。

       GetTailPosition():返回尾部元素的位置。

       遍历元素:

       GetNext():获取用于遍历下一个元素的方法。

       GetPrev():获取用于遍历的前一个元素的方法。

       获取或修改元素:

       CList类成员提供了对列表元素的获取和修改功能,便于用户对有序列表进行操作和管理。

更多相关资讯请点击【探索】频道>>>