紫云的程序人生
文章平均质量分 57
记录自己在软件开发中的一些学习与收获
梦李寻欢
纸上得来终觉浅,绝知此事要躬行.
展开
-
使用Pybind11,Python调用C++动态库
最近学习了一下pybind11,使用python来调用C++动态库的模式,在某些场景下有用,这里做一个记录。原创 2024-10-09 16:19:24 · 855 阅读 · 0 评论 -
数据库性能测试2:内存数据库
在内存模式下(相较与文件模式),duckdb与sqlite的写入性能都有较大的提升,而查询性能提升不大,可能是因为文件模式下,两者都会有缓存的原因。因为本次测试引入了我自己的一套内存数据库,相较于上一次的测试,本次对所有数据库增加了一个合约代码的索引,增加索引后,Duckdb的写入性能下降比较严重,而查询性能几乎没变。查询性能对比文件模式下,相差也不大,duckdb的内存模式下跟文件模式下查询耗时基本持平,sqlite内存模式比文件模式每次大约快1ms(约10%-25%)的样子。原创 2024-08-29 13:35:38 · 531 阅读 · 0 评论 -
protobuf与grpc编译
boringssl 中crypto编译错误,由于此工程编译需要访问golang的网页获取某些文件来生产 err_data.c 文件,没有翻墙工具的同学通常是无法完成的,我这里找另外一个有翻墙工具的同事帮忙生成了此文件,不过每次编译时候还要先失败一次,这时会在 grpc/build-dir/third_party/boringssl-with-bazel/crypto 目录下生成一个err_data.c 的文件,用准备好的err_data.c文件替换它再次编译即可。原创 2024-08-19 11:24:41 · 560 阅读 · 0 评论 -
数据库性能测试:Mysql、Sqlite、Duckdb
之前有创建两个额外的索引,同时那会还使用的是duckdb C++版本的API,于是乎,我在执行写入数据时发现写入速度成加速下降,最终写了一超过14个小时,才写到500万条数据的样子。我这边测试从创建表开始,首先是将tick数据写入表中,然后根据主键字段的子集(主键是四个字段,我取了其中的三个)进行查询10次,然后对全表进行一次查询。从索引查询来看,duckdb平均在10ms以下,sqlite不太稳定,有一些在10ms以下,也有一些到20ms级别,而mysql则是100ms级。原创 2024-08-12 15:05:10 · 1329 阅读 · 0 评论 -
使用duckdb
在读取该字段时其不能直接使用 duckdb_decimal 类型进行读取,因为其数据块中存储的字段的实际类型是int16,int32,int64或hugeint,具体使用那种类型的整型与定义的decimal的宽度有关,需要使用对应的整型类型来读取,然后通过对 duckdb_decimal 类型构造复制来获得对于的demical类型,要转为double类型,还需要调用 duckdb_decimal_to_double 函数进行转换。最近研究了一下duckdb的使用,也是踩了一些坑,这里记录一下。原创 2024-08-12 14:07:10 · 612 阅读 · 0 评论 -
使用Visual Studio 开发Linux C++项目
需要注意是,Visual Studio 提取头文件的过程相当的慢,会导致工程里面IntelliSense提升一大堆的错误,可以考虑使用远程工具将Linux头文件拷贝到本地缓存位置。Visual Studio 会在Linux系统上自动启动gdb,并使用Visual Studio 调试器的前端在Linux上提供完全保真的调试和体验。要使用Visual Studio 开发Linux C++项目,需要在安装时候勾选 Linux development with C++。仅CMake项目需要。原创 2024-07-29 14:47:43 · 453 阅读 · 0 评论 -
ItemsControl 类控件子项拖放
在装饰器里面封装这些事件,这里面定一个了一个依赖属性 ItemType,需要在使用装饰器时指定ItemType,应为ItemsSource集合中元素的类型,在拖放响应DropEvent 事件时进行校验,如果拖放的数据与ItemType类型一致,才接收拖放数据。要实现拖放功能,关键点还是在按下鼠标并移动时,调用 DoDragDrop 方法以触发拖动动作,然后在拖放目标上响应 DropEvent 事件。原创 2024-05-20 18:09:42 · 225 阅读 · 0 评论 -
WPF拖放控件
对拖放相关事件研究后发现,最终只需要在拖动源事件处理程序中调用 DoDragDrop 方法启动拖动操作,然后在拖放目标上,响应Drop事件。除了正常拖动(将Tab页从一个TabControl 拖动到另一个 TabControl 中),考虑将Tab页拖动到窗口之外的情况(浏览器在这种情况下会创建一个新的窗口来显示这个Tab页),我这里采用类似的方式,创建一个预设的子窗口来显示该Tab页面。此外,当Tab页面在原TabControl内部拖动时,根据拖动位置,调整Tab页面的顺序。原创 2024-05-20 15:25:36 · 695 阅读 · 0 评论 -
Ubuntu磁盘扩容
可以看到根目录的挂载点 ubuntu--vf-ubuntu--lv 的大小是100G,但是其父级 sda3 有463.8G的空间,考虑将其分配给 ubuntu--vg-ubuntu--lv 使用。发现根目录挂载点 ubuntu--vg-ubuntu--lv 增加至456G,可能还有一些空间被其它的占用了,暂时不用管它。这里Alloc 是已分配的磁盘空间,Free是还可以分配的磁盘空间。原创 2024-04-11 10:27:03 · 420 阅读 · 0 评论 -
Mysql配置文件
此版本mysql配置文件位置:/etc/mysql/mysql.conf.d/mysqld.cnf。现在是要的Mysql版本:8.0.36-0ubuntu0.20.04.1。原创 2024-02-20 10:55:33 · 155 阅读 · 0 评论 -
C++故障清单
在处理文本解析时有个地方必须要硬编码中文字符进去,于是遇到了这个问题。我这里的中文使用的UTF8编码,正确解析的情况下,是不会出现换行符的,这里肯定是编码识别出现了问题。看来是因为Source文件没有加BOM,被当做MBCS编码来解析了。这里使用Notepad++打开源文件,将其转换为带BOM的UTF8编码即可。C2001:常量中有换行符。原创 2023-12-29 16:45:44 · 365 阅读 · 0 评论 -
Mysql sql_mode参数配置
从错误信息可以看出是因为设置了sql_mode=ONLY_GROUP_BY参数导致的,看起来这个参数是将select 的内容严格限制在Group By 的参数集中。要解决这个问题,需要把这个参数移除掉。ONLY_FULL_GROUP_BY:对于GROUP BY聚合操作,如果在SELECT中的列,没有在GROUP BY中出现,那么这个SQL是不合法的,因为列不在GROUP BY从句中。把sql_mode参数里面ONLY_FULL_GROUP_BY移除掉,这种方式只能临时解决,如果mysql重启后,就会失效。原创 2023-12-23 12:01:07 · 257 阅读 · 0 评论 -
Linux 文本处理
在处理大文本时,使用VI打开会非常慢,通常只需要查看其中的少量信息,比如查看前多少行、或者文件尾多少行。这种情况下可以使用head和tail命令,这种方式查看起来会非常快。原创 2023-12-19 15:55:07 · 89 阅读 · 0 评论 -
.NET发布程序故障排查
首先看到单击程序后,看到加载的小圆圈后,程序始终没有打开,也没有任何提示,遇到这种情况是很郁闷的,这种情况下可以查看windows 事件查看器 - Windows日志 - 应用程序,这里面可以看到最近崩溃的应用程序错误。当知道是缺少C++的库了后,其实可以针对所使用的C++库,写一个C++库的测试程序,然后在这个电脑上运行C++库的测试程序,这样,在运行时windows 会弹窗提醒具体缺少什么库。我这里遇到的问题是依赖于某个C++的库,而C++的库缺少所依赖的运行环境,也就是VS的一些运行时库。原创 2023-12-06 17:44:36 · 197 阅读 · 0 评论 -
.Net 字符集与编解码
如果参数是一个对象,而对象中的字符串类型需要在定义封装对象的位置,通过StructLayout 属性的CharSet 来设置。这里首先测试了.Net 在Windows环境下运行情况下,.Net 默认使用ANSI 编解码,其中在 DllImport 中指定的 CharSet 对导出函数的直接字符串参数生效。这里主要针对于使用C++ API是遇到的一些编码被封送的情况测试。跟上面类似,但是Unicode 传送的不成功,想必是类型问题,Unicode 对应C++中应该对应使用wchar* 数组。原创 2023-11-30 15:17:05 · 516 阅读 · 0 评论 -
.NET 使用配置文件
我简单测试了一下json格式配置文件,在这里记录一下,方便以后查看。创建json格式文件:appsettings.json。原创 2023-11-22 14:08:08 · 872 阅读 · 0 评论 -
Ubuntu 搭建FTP服务
综合来说,当开启黑名单时(userlist_deny=YES,userlist_enable=YES),既不在/etc/ftpusers中,又不在 userlist_file 所指向名单文件中的用户可以登录FTP;而 userlist_deny 用于指示该名单为黑名单还是白名单,当userlist_deny=YES时,userlist_file中的名单为黑名单,而当 userlist_deny=NO 时,userlist_file中的名单为白名单。而对于一般的文件的话,则是用 666-022=644。原创 2023-11-20 18:28:33 · 676 阅读 · 0 评论 -
Asp.Net Core 中使用配置文件
经测试,通过IDE直接启动时,使用的是appsettings.Development.json文件,而发布后的程序启动时,使用的则是 appsettings.Production.json文件。这里主要介绍使用设置文件,设置文件包含一组名称类似的文件:appsettings.json,appsettings.{Environment}.json。ASP.NET Core 中的应用程序配置是使用一个或多个配置程序提供程序执行的。原创 2023-11-08 17:21:34 · 895 阅读 · 1 评论 -
Ubuntu安装.Net SDK
选择自己对应系统版本的链接辅助即可。我这里使用的是 Ubuntu 20.04,因为在这个版本.Net 在Ubuntu包源存储库中不可用,需要手动添加Microsoft包存储库。使用 APT 进行安装可通过几个命令来完成。安装 .NET 之前,请运行以下命令,将 Microsoft 包签名密钥添加到受信任密钥列表,并添加包存储库。原创 2023-11-08 15:45:31 · 738 阅读 · 0 评论 -
WPF枚举绑定
此示例演示如何绑定到枚举。遗憾的是,没有直接方法可以将枚举用作数据绑定源。但是,Enum.GetValues(Type) 方法可返回值的集合。这些值可以包装在 ObjectDataProvider 中并用作数据源。ObjectDataProvider 类型提供了一种在 XAML 中创建对象并将其用作数据源的便捷方式。使用 ObjectDataProvider 类型包装枚举类型本身提供的枚举值数组。实际上,XAML 正在分解方法调用、方法名称、参数和返回类型。原创 2023-09-20 16:17:05 · 708 阅读 · 0 评论 -
WPF控件模板2
如果创建元素类型样式ScrollBar,并将其添加到窗口的Resources集合中,对于窗口的所有控件,无论何时使用ScrollBar控件,都会具有新样式的滚动条,这可能正是您所希望的效果。为成功地创建控件模板,需要仔细查看相关控件的标准模板,并注意分析这些技术的用法,然后将它们应用到自己的模板中。这是该模板特有的实现细节,可确保Thumb元素总有相同的尺寸(通常,滑块根据内容按比例地改变尺寸,因此如果滚动的内容在窗口中基本上能够显示,这是滑块会变得较长)。按钮控件的模板可分解成几个较简单的部分。原创 2023-09-20 13:54:39 · 359 阅读 · 0 评论 -
WPF控件模板
简单的说,自定义控件是必须的内容——它们是实现新颖时髦的用户界面的唯一方法,但支持它们并将它们集成到应用程序中也是一件棘手的事情。如果查看Button类的控件模板,就会发现在模板绑定的使用方法上,与自定义模板是完全相同的——获取为按钮指定的内边距,并将它转换为ContentPresenter元素周围的外边距。当选择使用类似Button的控件时,是希望得到类似按钮的行为(换句话说,选择的是一个元素,该元素提供了能被单击的内容,通过单击来触发动作,并且可用做窗口上的默认按钮或取消按钮)。原创 2023-09-19 16:38:51 · 526 阅读 · 0 评论 -
WPF行为
然而,WPF支持触发器,行为特性包含自己的触发器系统,而触发器系统与WPF模型不匹配,这确实令人感到有些困惑。其思想很简单:创建封装了一些通用用户界面功能的行为,这一功能可以是基本功能(如启动故事板或导航到超链接),也可以是复杂功能(如处理多点触摸交互,或构件使用实时物理引擎的碰撞模型)。一旦构建功能,就可将他们添加到任意应用程序的另一个控件中,具体方法是将该控件链接到适当的行为并设置行为的属性。但通过付出更多一点的努力,可将该代码转换为可重用的行为,该行为可为Canvas面板上的所有元素提供拖动支持。原创 2023-09-18 16:04:40 · 554 阅读 · 0 评论 -
WPF样式
样式是可应用与元素的属性值集合。WPF样式也支持触发器,当属性发生变化时,可通过触发器改变控件的样式,并可以通过模板重新定义控件的内置外观。除非有特殊原因要求一个样式继承自另一个样式(例如,第二个样式是第一个样式的特例,并且只改变了继承来的大量设置中的几个特征),否则不要使用样式继承。如果需要使用此功能,可能更好的选择是事件触发器,它以声明的方式定义了所希望的行为(并且不需要任何代码)。唯一的规则是,如果两次设置了同一个属性,最后的属性设置器(在继承链中最远的派生类中设置器)会覆盖其他以前的定义。原创 2023-09-15 13:44:07 · 313 阅读 · 0 评论 -
WPF命令
编写代码完成这些工作(并在后面添加代码以启用这些控件)是很麻烦的,更糟的是,如果没有正确完成这项工作,可能会使不同状态的代码块不正确的相互重叠,从而导致某个控件在可应该可用时而被启用。然而,有工具栏上的按钮触发的命令是完全独立的元素。这个过程之所以能够无缝工作,是因为按钮被放到工具栏上,ToolBar提供了一些内置逻辑,可将其子元素的CommandTarget属性动态设置为当前具有焦点的控件(从技术角度看,ToolBar控件一直在关注着其父元素,及窗口,并在上下文中查找最近具有焦点的控件,即文本框。原创 2023-09-08 18:23:54 · 672 阅读 · 0 评论 -
WPF元素绑定
如果希望根据其他运行时信息修改绑定,或者根据环境创建不同的绑定,这时使用代码创建绑定通常更合理(此外,也可以在窗口的Resources集合中定义可能希望使用的每个绑定,并只添加使用合适的绑定对象调用SetBinding() 方法的代码)。如果指定的元素或属性不存在,那么不会收到任何指示,只是不能在目标属性中显示数据。使用代码创建绑定时,先创建一个绑定对象,构造函数参数指定Path字段,然后设置Binding相关的属性值,通过绑定目标的SetBinding函数,将绑定目标的属性与Binding对象关联即可。原创 2023-09-05 17:35:47 · 902 阅读 · 0 评论 -
DataGrid
它还提供了行的 DataGridRow 对象,允许开发人员使用不同的颜色或不同的字体设置行的格式。对于简单的 DataGridTextColumn,该元素是 TextBlock,对于DataGridCheckBoxColumn ,单元格内部的元素是复选框,可使用 EditingElementStyle 属性为编辑列时使用的元素提供样式。例如,不能控制列的顺序、每列的宽度、如何格式化列中的值以及应该放在顶部的标题文本的内容。2、可配置行细节区域,从而只为选择的行显示该区域,当不需要时允许用户折叠额外的细节。原创 2023-09-04 18:11:17 · 193 阅读 · 0 评论 -
TreeView
TreeView 控件经常用于包含大量数据,这是因为TreeView 控件的显示是能够折叠的。完全可以在TreeView 控件中省略不显示的信息,以便降低开销。可通过处理这两个事件即时填充丢失的节点或丢弃不需要的节点。相反,每个TreeViewItem 对象都是单独的ItemsControl 控件,可以包含更多TreeViewItem 对象。尽管这个标记工作的很好,单分解每个数据模板并通过数据类型(而不是通过位置)将模板应用到数据对象的情况更加普遍。实际上,现在有两个模板,每个模板用于树控件中的每个层次。原创 2023-09-04 13:52:57 · 398 阅读 · 0 评论 -
ListView
这里除了ViewBase 所需的DefaultStyleKey 与 ItemContainerDefaultStyleKey 外,还另外定义了三个属性:ItemTemplate、SelectedBackground、SelectedBorderBrush,其中ItemTemplate用于使用时提供正确的数据模板,SelectedBackground与SelectedBorderBrush用于为视图传递额外信息,在视图样式中可以绑定到这两个属性来使用。ListView 继承自简单的没有特色的ListBox。原创 2023-09-04 10:45:15 · 127 阅读 · 0 评论 -
WPF数据视图
例如,可将同一个集合绑定到两个不同的列表,并对集合进行过滤以显示不同的记录。我实测下来,绑定自同一个数据源的ItemsControl控件会共享一个View,当对该View进行筛选、排序时,会应用到所有绑定到该数据源的控件。将集合绑定到ItemsControl控件时,会不加通告的在后台创建数据视图——位于数据源和绑定的控件之间。数据视图是进入数据源的窗口,可以跟踪当前项,并且支持各种功能,如排序、过滤、分组。可以看到,可以直接通过数据源来获取视图,这也表明,绑定到同一个数据源的控件会公用一个视图。原创 2023-09-01 10:20:18 · 1544 阅读 · 0 评论 -
WPF数据模板
样式提供了基本的格式化能力,但它们不能消除到目前为止看到的列表的最重要的局限性:不管如何修改ListBoxItem,它都只是ListBoxItem,而不是功能更强大的元素组合。模板选择器是一种更强大的工具,可以根据不同的条件应用完全不同的模板。然而WPF另有一个工具可突破这个相当大的限制,并允许组合使用来自绑定对象的多个属性,并以特定的方式排列它们或显示比简单字符串更高级的可视化表示。实现了IValueConverter接口的类,能够将值从绑定的对象转换为可用于设置模板中与格式化相关的属性的值。原创 2023-08-31 15:34:07 · 784 阅读 · 0 评论 -
WPF列表样式
WPF的数据绑定系统自动生成列表项对象,为单个项应用所需的样式不是很容易。如果设置了ItemContainerStyle 属性,当创建列表项时,列表控件会将其向下传递给每个项。对于ListBox控件,每个项有ListBoxItem 对象表示,对于CombBox 控件,则对应是 CombBoxItem。可以使用样式选择器来为不同的子项提供不同的样式,自定义样式选择器需要继承自 StyleSelector 类,需要重写 SelectStyle() 方法。也可以直接将样式设置到ListBox层次。原创 2023-08-30 16:35:05 · 1305 阅读 · 0 评论 -
WPF数据转换
多重绑定的值转换器需要实现的接口是 IMultiValueConverter,与 IValueConverter 接口比较类似,只是转换函数的第一个参数改成了数组形式。可以看到后面两个StringFormat属性以花括号 {} 开头,完整值是 {}{0:C},而不是 {0:C},第一个则只有 {0:C},这是因为在StringFormat 值以花括号开头时需要 {} 转义序列。该功能更强大,使用该功能可以将任意类型的源数据转换为任意类型的对象表示,然后可以传递到关联的控件。原创 2023-08-30 14:04:42 · 1286 阅读 · 0 评论 -
WPF 数据验证
可以在设置属性时抛出异常,通常WPF会忽略所有在设置属性时抛出的异常,但可以进行配置,从而显示更有帮助的可视化指示。使用装饰层,可添加可视化装饰来指示错误,而不用替换控件背后的控件模板或改变窗口的布局。如果需要执行对两个或更多个绑定值的验证,可以通过 BindingGroup 来实现,将需要校验的多个控件放置于同一个容器中,在容器级别应用验证规则,需要通过事件主动触发验证,通常是子组件失去焦点时。更好的是,因为是在不同类中定义验证,可以很容易的在存储类似数据类型的多个绑定中重用验证。原创 2023-08-29 15:57:15 · 1673 阅读 · 0 评论 -
列表类控件虚拟化
1、在ScrollViewer中放置列表控件,ScrollViewer为其子内容提供了一个无限虚拟空间,在这个虚拟空间内,列表控件可以完整尺寸渲染自身,显示所有子项。可以通过延迟滚动来进一步提升性能,开启延迟滚动后,在滚动滑块时不会更新列表显示,只有当用户释放滚动滑块时才刷新。TreeView也是使用的VirtualizingStackPanel面板,但是默认情况下关闭了该支持,可以通过配置 VirtualizingStackPanel.IsVirtualizing="True" 来启用。原创 2023-08-28 16:46:03 · 860 阅读 · 0 评论 -
WPF数据绑定
其中,ComboBox绑定到ListBox所选择的项,根据ListBox选择的项的Instruments属性来填充其子项,而下面的StackPanel 的 DataContext 又绑定到ComboBox选择的项,三个TextBlock控件展示ComboBox所选择项的各项属性。绑定到集合的数据类型可以是任意类型的集合,唯一的要求是支持IEnumerable 接口,数组、各种类型的集合以及许多特殊的封装了数据项组的对象都支持该接口。在填写表单时候,经常会遇到根据前面选定的项,自动调整后面选项的内容的情况。原创 2023-08-28 14:40:21 · 662 阅读 · 0 评论 -
C#使用C++动态库2
目前在封装class类型参数的字符串类型字段时,仅尝试 UnmanagedType.ByValTStr 类型成功,使用UnmanagedType.LPUTF8Str时会遇到 System.AccessViolationException 异常。C++回调函数里面的class的指针类型参数,在C#中还是用class来对应,在用struct的ref形式时遇到的一个问题是,C++的指针为空时,在回调时候会遇到 System.NullReferenceException 异常。原创 2023-08-23 16:44:09 · 458 阅读 · 0 评论 -
WPF使用依赖注入
在使用依赖注入后,我发现在App里面完成一些初始化内容更合适,包括MainWindow也通过容器生成,需要注意的是,记得把App.xaml中的 StartupUri更改为 Startup,并把值改为自定义的启动函数,在启动函数里面调用MainWindow的Show方法。现在依赖注入在.Net里面已经普及,自己常写一些简单的demo倒是无所谓,但偶尔写一点正式的工程,也免不了要使用一下,于是总结了一下在WPF里面使用依赖注入。原创 2023-08-22 11:20:01 · 1250 阅读 · 0 评论 -
使用NLog
C#中日志模块,.Net提供了一套日志接口,但是内置的日志提供程序只有Console、Debug、EventSource、EventLog,没有常规的日志提供程序。微软推荐了一些第三方日志提供程序库,我这里选择了。原创 2023-08-21 17:41:14 · 325 阅读 · 0 评论 -
C++ Unicode、Utf8、GBK编码之间转换
C++标准库从C++11开始提供了std::codecvt_utf8和std::codecvt_byname两个转换器来完成编码转换,其中std::codecvt_utf8用于 utf8编码与unicode之间的转换,GBK与unicode之间的转换则需要通过std::codecvt_byname 来完成,并需要指定locale_name参数,此参数windows与linux下并不相同。原创 2023-06-09 14:17:00 · 3043 阅读 · 0 评论