.Net 字符集与编解码
0 .NET 字符集编解码
.Net 内部使用的字符集是Unicode,如果需要编码为其他诸如GBK、UTF8编码,可以通过Encoding 类来实现。
using System.Text;void PrintBytes(byte[] bytes)
{foreach (var b in bytes){Console.Write("{0:X} ", b);}Console.WriteLine();
}Encoding.RegisterProvider(CodePagesEncodingProvider.Instance);string str = "主账号";var gbkBytes = Encoding.GetEncoding("gbk").GetBytes(str); //获取GBK编码
var utf8Bytes = Encoding.UTF8.GetBytes(str); //获取UTF8编码
var unicodeBytes = Encoding.Unicode.GetBytes(str); //获取Unicode编码PrintBytes(gbkBytes);
PrintBytes(utf8Bytes);
PrintBytes(unicodeBytes);var gbkStr = Encoding.GetEncoding("gbk").GetString(gbkBytes); //使用GBK解码
var utf8Str = Encoding.UTF8.GetString(utf8Bytes); //使用UTF8解码
var unicodeStr = Encoding.Unicode.GetString(unicodeBytes); //使用Unicode解码Console.WriteLine(gbkStr);
Console.WriteLine(utf8Str);
Console.WriteLine(unicodeStr);
输出:
D6 F7 D5 CB BA C5
E4 B8 BB E8 B4 A6 E5 8F B7
3B 4E 26 8D F7 53
主账号
主账号
主账号
在使用C++API时,当遇到字符串处理时难免会需要处理字符编码的问题。这里主要针对于使用C++ API是遇到的一些编码被封送的情况测试。
1 Windows环境下
这里首先测试了.Net 在Windows环境下运行情况下,.Net 默认使用ANSI 编解码,其中在 DllImport 中指定的 CharSet 对导出函数的直接字符串参数生效。CharSet 取值与C++ API 端接收到的字符串情况对应如下:
1.1 请求函数:C# => C++
1.1.1 测试函数字符串参数编码
输入文字:主账号
CharSet | C++API端接收到的字符集 | 输出Byte值 |
---|---|---|
不设置 | GBK | D6 F7 D5 CB BA C5 |
Ansi | GBK | D6 F7 D5 CB BA C5 |
Unicode | Unicode | 3B 4E 26 8D F7 53 |
Auto | Unicode | 3B 4E 26 8D F7 53 |
None | GBK | D6 F7 D5 CB BA C5 |
测试接口代码:
//对这个接口分别设置为以下5种情况进行测试[DllImport(LibName, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.Auto, allingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.None, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);
1.1.2 测试函数结构体参数中的字符串编码
在这个 DllImport 中设置的CharSet 仅对接口函数的直接字符串类型生效。如果参数是一个对象,而对象中的字符串类型需要在定义封装对象的位置,通过StructLayout 属性的CharSet 来设置。我这里测试下来,CharSet 取值与C++ API 端接收到的字符串情况对应如下:
输入文字:主账号
CharSet | C++API端接收到的字符集 | 输出Byte值 |
---|---|---|
不设置 | GBK | D6 F7 D5 CB BA C5 |
Ansi | GBK | D6 F7 D5 CB BA C5 |
Unicode | null | |
Auto | null | |
None | GBK | D6 F7 D5 CB BA C5 |
跟上面类似,但是Unicode 传送的不成功,想必是类型问题,Unicode 对应C++中应该对应使用wchar* 数组。
测试接口及定义结构体的代码:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class StepReqAddPrimaryAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? PrimaryAccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? PrimaryAccountName;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? BrokerPassword;public int ChannelID;public bool IsAllowLogin;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int RiskGroupID;public int CommissionGroupID;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class StepReqUpdatePrimaryAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? PrimaryAccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? PrimaryAccountName;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? BrokerPassword;public int ChannelID;public bool IsAllowLogin;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int RiskGroupID;public int CommissionGroupID;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.None)]
public class StepReqAddAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? AccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? AccountName;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int TradeGroupID;public int RiskGroupID;public int CommissionGroupID;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class StepReqUpdateAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? AccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? AccountName;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int TradeGroupID;public int RiskGroupID;public int CommissionGroupID;
}
[DllImport(LibName, CharSet=CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]public static extern int ReqAddPrimaryAccount(StepReqAddPrimaryAccount reqAddPrimaryAccount, int requestID);[DllImport(LibName, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern int ReqUpdatePrimaryAccount(StepReqUpdatePrimaryAccount reqUpdatePrimaryAccount, int requestID);[DllImport(LibName, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int ReqAddAccount(StepReqAddAccount reqAddAccount, int requestID);[DllImport(LibName, CharSet = CharSet.None, CallingConvention = CallingConvention.StdCall)]public static extern int ReqUpdateAccount(StepReqUpdateAccount reqUpdateAccount, int requestID);
1.2 回调函数:C++ => C#
返回值:正确
C++中编码:GBK
CharSet | C#回调函数接收到字符集 | 解码情况 |
---|---|---|
不设置 | GBK | 正确 |
Ansi | GBK | 正确 |
Unicode | null | 乱码 |
Auto | null | 乱码 |
None | GBK | 正确 |
C++中编码:Utf8
相关测试代码:
//依次将CharSet 设置为:不设置值、Ansi、Unicode、Auto、None,进行测试
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class StepRspInfo
{public int ErrorID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]public string? ErrorMsg;
}
回调委托定义:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void OnRspAdminUserLogin(StepRspAdminUserLogin? rspAdminUserLogin, StepRspInfo? rspInfo, int requestID, bool isLast);
2 Linux环境下
2.1 请求函数: C# => C++
2.1.1 测试函数字符串参数编码
输入文字:主账号
CharSet | C++API端接收到的字符集 | 输出Byte值 |
---|---|---|
不设置 | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
Ansi | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
Unicode | Unicode | 3B 4E 26 8D F7 53 |
Auto | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
None | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
测试接口代码:
//对这个接口分别设置为以下5种情况进行测试[DllImport(LibName, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.Auto, allingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);[DllImport(LibName, CharSet=CharSet.None, CallingConvention = CallingConvention.StdCall)]public static extern void RegisterFront(string ip, int port);
2.1.2 测试函数结构体参数中的字符串编码
通过StructLayout 属性的CharSet 来设置结构体中的字符串编码,CharSet 取值与C++ API 端接收到的字符串情况对应如下:
输入文字:主账号
CharSet | C++API端接收到的字符集 | 输出Byte值 |
---|---|---|
不设置 | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
Ansi | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
Unicode | null | |
Auto | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
None | UTF8 | E4 B8 BB E8 B4 A6 E5 8F B7 |
跟上面类似,但是Unicode 传送的不成功,想必是类型问题,Unicode 对应C++中应该对应使用wchar* 数组。
测试接口及定义结构体的代码:
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class StepReqAddPrimaryAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? PrimaryAccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? PrimaryAccountName;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? BrokerPassword;public int ChannelID;public bool IsAllowLogin;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int RiskGroupID;public int CommissionGroupID;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Unicode)]
public class StepReqUpdatePrimaryAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? PrimaryAccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? PrimaryAccountName;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? BrokerPassword;public int ChannelID;public bool IsAllowLogin;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int RiskGroupID;public int CommissionGroupID;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.None)]
public class StepReqAddAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? AccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? AccountName;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int TradeGroupID;public int RiskGroupID;public int CommissionGroupID;
}
[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
public class StepReqUpdateAccount
{[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 9)]public string? TradingDay;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 32)]public string? AccountID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? AccountName;public AccountStatusType AccountStatus;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)]public string? Password;public int TradeGroupID;public int RiskGroupID;public int CommissionGroupID;
}
[DllImport(LibName, CharSet=CharSet.Ansi, CallingConvention = CallingConvention.StdCall)]public static extern int ReqAddPrimaryAccount(StepReqAddPrimaryAccount reqAddPrimaryAccount, int requestID);[DllImport(LibName, CharSet = CharSet.Unicode, CallingConvention = CallingConvention.StdCall)]public static extern int ReqUpdatePrimaryAccount(StepReqUpdatePrimaryAccount reqUpdatePrimaryAccount, int requestID);[DllImport(LibName, CharSet = CharSet.Auto, CallingConvention = CallingConvention.StdCall)]public static extern int ReqAddAccount(StepReqAddAccount reqAddAccount, int requestID);[DllImport(LibName, CharSet = CharSet.None, CallingConvention = CallingConvention.StdCall)]public static extern int ReqUpdateAccount(StepReqUpdateAccount reqUpdateAccount, int requestID);
2.2 回调函数: C++ => C#
返回值:正确
C++中编码:GBK
CharSet | C#解码情况 |
---|---|
不设置 | 乱码 |
Ansi | 乱码 |
Unicode | 乱码 |
Auto | 乱码 |
None | 乱码 |
C++中编码:Utf8
相关测试代码:
//依次将CharSet 设置为:不设置值、Ansi、Unicode、Auto、None,进行测试
[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
public class StepRspInfo
{public int ErrorID;[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 256)]public string? ErrorMsg;
}
回调委托定义:
[UnmanagedFunctionPointer(CallingConvention.StdCall)]
public delegate void OnRspAdminUserLogin(StepRspAdminUserLogin? rspAdminUserLogin, StepRspInfo? rspInfo, int requestID, bool isLast);
3 结论
当在与C++ API 交互时,如果在windows平台运行,建议使用GBK编码进行通信;而在Linux平台运行的话,建议使用 UTF8编码进行通信。
相关文章:
.Net 字符集与编解码
0 .NET 字符集编解码 .Net 内部使用的字符集是Unicode,如果需要编码为其他诸如GBK、UTF8编码,可以通过Encoding 类来实现。 using System.Text;void PrintBytes(byte[] bytes) {foreach (var b in bytes){Console.Write("{0:X} ", b);}Conso…...

Spinnaker 基于 jenkins 触发部署
jenkins job 触发部署 将 Jenkins 设置为 Spinnaker 中的持续集成 (CI) 系统可让您使用 Jenkins 触发管道、向管道添加 Jenkins 阶段或向管道添加脚本阶段。 前置要求: 已在kubernetes中部署spinnaker已准备可用的jenkins实例 启用 jenkins触发器 官方文档&…...

FLASK博客系列6——数据库之谜
我们上一篇已经实现了简易博客界面,你还记得我们的博客数据是自己手动写的吗?但实际应用中,我们是不可能这样做的。大部分程序都需要保存数据,所以不可避免要使用数据库。我们这里为了简单方便快捷,使用了超级经典的SQ…...
Clickhouse UPDATE 和 DELETE操作
历史: 在OLAP数据库中,可变数据(Mutable data)通常是不被欢迎的,Clickhouse也是如此,早期版本不支持UPDATE和DELTE操作。在Clickhouse 1.1.54388版本之后才支持UPDATE和DELETE操作,适用于Merge…...

golang channel执行原理与代码分析
使用的go版本为 go1.21.2 首先我们写一个简单的chan调度代码 package mainimport "fmt"func main() {ch : make(chan struct{})go func() {ch <- struct{}{}ch <- struct{}{}}()fmt.Println("xiaochuan", <-ch)data, ok : <-chfmt.Println(&…...

OpenCvSharp从入门到实践-(04)色彩空间
目录 1、GRAY色彩空间 2、从BGR色彩空间转换到GRAY色彩空间 2.1色彩空间转换码 2.2实例 BGR色彩空间转换到GRAY色彩空间 3、HSV色彩空间 4、从BGR色彩空间转换到HSV色彩空间 4.1色彩空间转换码 4.2实例 BGR色彩空间转换到HSV色彩空间 1、GRAY色彩空间 GRAY色彩空间通常…...

100.有序数组的平方(力扣)
代码解决一 class Solution { public:// 函数接受一个整数数组,返回每个元素平方值排序后的结果vector<int> sortedSquares(vector<int>& nums) {int len nums.size(); // 获取数组的长度vector<int> v; // 创建一个新的数组,用…...

微服务--01--简介、服务拆分原则
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 微服务微服务架构,是服务化思想指导下的一套最佳实践架构方案。服务化,就是把单体架构中的功能模块拆分为多个独立项目。 单体架构微服务架构…...

IntelliJ IDEA安装使用教程
IntelliJ IDEA是一个流行的Java 集成开发环境(IDE),由JetBrains公司开发。它是一款全功能的IDE,支持多种编程语言,如Java、Kotlin、Groovy、Scala、Python、JavaScript、HTML、CSS等等。IntelliJ IDEA 提供了高效的代码…...

校园门禁可视化系统解决方案
随着科技的持续进步,数字化校园在教育领域中的地位日益上升,各种智能门禁、安防摄像头等已遍布校园各个地方,为师生提供安全便捷的通行体验。然而数据收集分散、缺乏管理、分析困难等问题也逐渐出现,在这个数字化环境中࿰…...

rest_framework_django学习笔记一(序列化器)
rest_framework_django学习笔记一(序列化器) 一、引入Django Rest Framework 1、安装 pip install djangorestframework2、引入 INSTALLED_APPS [...rest_framework, ]3、原始RESTful接口写法 models.py from django.db import models 测试数据 仅供参考 INSERT INTO de…...

面试题:什么是负载均衡?常见的负载均衡策略有哪些?
文章目录 一、负载均衡二、负载均衡模型分类三、CDN负载均衡四、LVS负载均衡4.1 LVS 支持的三种模式4.1.1 DR 模式4.1.2 TUN 模式4.1.3 NAT 模式 4.2 LVS 基于 Netfilter 的框架实现 五、负载均衡策略是什么六、常用负载均衡策略图解6.1 轮询6.2 加权轮询6.3 最少连接数6.4 最快…...
精通Git(第2版)读书笔记
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言第 1章 入门 11.1 关于版本控制 11.1.1 本地版本控制系统 1 第 2章 Git基础 132.1 获取Git仓库 132.1.1 在现有中初始化Git仓库 132.1.2 克隆现有仓库 14 2.2 在…...

XUbuntu22.04之OBS30.0设置录制音频降噪(一百九十六)
简介: CSDN博客专家,专注Android/Linux系统,分享多mic语音方案、音视频、编解码等技术,与大家一起成长! 优质专栏:Audio工程师进阶系列【原创干货持续更新中……】🚀 优质专栏:多媒…...

渗透测试学习day4
文章目录 靶机:SequelTask1Task2Task3Task4Task5Task6Task7Task8 靶机:CrocodileTask1Task2Task3Task4Task5Task6Task7Task8Task9Task10 靶机:ResponderTask1Task2Task3Task4Task5Task6Task7Task8Task9Task10Task11 靶机:ThreeTas…...

Deepin使用记录-deepin系统下安装RabbitMq
目录 0、引言 1、由于RabbitMq是erlang语言开发的,所有需要先安装erlang 2、更新源并安装RabbitMq 3、安装完成之后,服务是启动的,可以通过以下语句查看状态 4、这样安装完成之后,是看不到web页面的,需要再安装一…...

【腾讯云云上实验室】用向量数据库——实现高效文本检索功能
文章目录 前言Tencent Cloud VectorDB 简介Tencent Cloud VectorDB 使用实战申请腾讯云向量数据库腾讯云向量数据库使用步骤腾讯云向量数据库实现文本检索 结论和建议 前言 想必各位开发者一定使用过关系型数据库MySQL去存储我们的项目的数据,也有部分人使用过非关…...

Pytorch中的gather的理解和用法
Pytorch中的gather的理解和用法 这个Gather的用法花费了点时间,我相信很多人一开始不太懂。 跟着我简单理解。 首先样例是: tensor([[ 3, 4, 5],[ 6, 7, 8],[ 9, 10, 11]])然后index: [[2, 1, 0]]然后执行的代码: tensor_0.gather(0…...
唯创知音WTN6系列语音芯片:高音频采样率与精细音量控制赋能广泛应用
在语音芯片领域,唯创知音的WTN6系列语音芯片以其出色的性能和广泛的应用领域,无疑是行业的一颗璀璨明星。近期,该系列芯片实现了音频采样率32kHz的突破,以及16级音量控制的精细调节,进一步提升了其在各类应用中的表现。…...
机器人分类
从发展阶段分类: 1第一代机器人2第二代机器人3第三代机器人:智能型机器人。生于90年代。具有传感器,以前的机器人都不具有传感器 从控制方式分类:(我觉得这个分类好乱) 操作型机器人:可自动控…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...

css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
DockerHub与私有镜像仓库在容器化中的应用与管理
哈喽,大家好,我是左手python! Docker Hub的应用与管理 Docker Hub的基本概念与使用方法 Docker Hub是Docker官方提供的一个公共镜像仓库,用户可以在其中找到各种操作系统、软件和应用的镜像。开发者可以通过Docker Hub轻松获取所…...
uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖
在前面的练习中,每个页面需要使用ref,onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入,需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

Opencv中的addweighted函数
一.addweighted函数作用 addweighted()是OpenCV库中用于图像处理的函数,主要功能是将两个输入图像(尺寸和类型相同)按照指定的权重进行加权叠加(图像融合),并添加一个标量值&#x…...

Springcloud:Eureka 高可用集群搭建实战(服务注册与发现的底层原理与避坑指南)
引言:为什么 Eureka 依然是存量系统的核心? 尽管 Nacos 等新注册中心崛起,但金融、电力等保守行业仍有大量系统运行在 Eureka 上。理解其高可用设计与自我保护机制,是保障分布式系统稳定的必修课。本文将手把手带你搭建生产级 Eur…...

vue3+vite项目中使用.env文件环境变量方法
vue3vite项目中使用.env文件环境变量方法 .env文件作用命名规则常用的配置项示例使用方法注意事项在vite.config.js文件中读取环境变量方法 .env文件作用 .env 文件用于定义环境变量,这些变量可以在项目中通过 import.meta.env 进行访问。Vite 会自动加载这些环境变…...

使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台
🎯 使用 Streamlit 构建支持主流大模型与 Ollama 的轻量级统一平台 📌 项目背景 随着大语言模型(LLM)的广泛应用,开发者常面临多个挑战: 各大模型(OpenAI、Claude、Gemini、Ollama)接口风格不统一;缺乏一个统一平台进行模型调用与测试;本地模型 Ollama 的集成与前…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...