PP-OCRv5 C++封装DLL C#调用源码分享

article/2025/9/9 0:46:30

目录

说明

效果

C#调用效果

项目

C#

C++

头文件

源文件

C#调用

下载


说明

C++封装DLL,C#调用源码分享

效果

C#调用效果

图片

项目

C#

图片

C++

图片

头文件

#include <windows.h>
#include <iostream>
#include <opencv2/opencv.hpp>
#include <string>using namespace std;
using namespace cv;//ocr  初始化
extern "C" _declspec(dllexport) int __cdecl init(void** engine, int cpu_threads, bool enable_mkldnn, char* det_model_dir, int limit_side_len, double det_db_thresh, double det_db_box_thresh, double det_db_unclip_ratio, bool use_dilation, bool cls, bool use_angle_cls, char* cls_model_dir, double cls_thresh, double cls_batch_num, char* rec_model_dir, char* rec_char_dict_path, int rec_batch_num, int rec_img_h, int rec_img_w, char* msg);//识别
extern "C" _declspec(dllexport) int __cdecl ocr(void* engine, Mat * image, char* msg, char** ocr_result, int* ocr_result_len);//释放
extern "C" _declspec(dllexport) int __cdecl destroy(void* engine, char* msg);//structure 初始化
extern "C" _declspec(dllexport) int __cdecl structure_init(void** engine, int cpu_threads, bool enable_mkldnn, char* det_model_dir, int limit_side_len, double det_db_thresh, double det_db_box_thresh, double det_db_unclip_ratio, bool use_dilation, bool cls, bool use_angle_cls, char* cls_model_dir, double cls_thresh, double cls_batch_num, char* rec_model_dir, char* rec_char_dict_path, int rec_batch_num, int rec_img_h, int rec_img_w, int table_max_len, int table_batch_num, char* table_model_dir, char* table_char_dict_path, char* msg);//structure
extern "C" _declspec(dllexport) int __cdecl structure(void* engine, Mat * image, char* msg, char** ocr_result, int* ocr_result_len);//释放
extern "C" _declspec(dllexport) int __cdecl structure_destroy(void* engine, char* msg);

源文件

#define _CRT_SECURE_NO_WARNINGS#include "pch.h"
#include <paddleocr.h>
#include "src/json.cpp"
#include <args.h>
#include <chrono>
#include <objbase.h>using json = nlohmann::json;
using namespace PaddleOCR;#include<locale>
#include <codecvt>
#include <paddlestructure.h>//初始化
int __cdecl init(void** engine, int cpu_threads, bool enable_mkldnn, char* det_model_dir, int limit_side_len, double det_db_thresh, double det_db_box_thresh, double det_db_unclip_ratio, bool use_dilation, bool cls, bool use_angle_cls, char* cls_model_dir, double cls_thresh, double cls_batch_num, char* rec_model_dir, char* rec_char_dict_path, int rec_batch_num, int rec_img_h, int rec_img_w, char* msg) {try {FLAGS_cpu_threads = cpu_threads;FLAGS_enable_mkldnn = enable_mkldnn;FLAGS_visualize = false;//det FLAGS_det_model_dir = det_model_dir;FLAGS_limit_side_len = limit_side_len;FLAGS_det_db_thresh = det_db_thresh;FLAGS_det_db_box_thresh = det_db_box_thresh;FLAGS_det_db_unclip_ratio = det_db_unclip_ratio;FLAGS_use_dilation = use_dilation;//clsFLAGS_cls = cls;FLAGS_use_angle_cls = use_angle_cls;FLAGS_cls_model_dir = cls_model_dir;FLAGS_cls_thresh = cls_thresh;FLAGS_cls_batch_num = cls_batch_num;//recFLAGS_rec_model_dir = rec_model_dir;FLAGS_rec_char_dict_path = rec_char_dict_path;FLAGS_rec_batch_num = rec_batch_num;FLAGS_rec_img_h = rec_img_h;FLAGS_rec_img_w = rec_img_w;PPOCR* _engine = new PPOCR();*engine = _engine;strcpy_s(msg, 128, "init success");return 0;}catch (...) {std::cout << "init error" << std::endl;strcpy_s(msg, 128, "init error");
return -1;}}//识别
int __cdecl ocr(void* engine, Mat* image, char* msg, char** ocr_result, int* ocr_result_len) {
if (engine == nullptr){strcpy_s(msg, 128, "engine is nullptr");
return -1;}PPOCR* _engine = (PPOCR*)engine;//auto start = std::chrono::steady_clock::now();std::vector<OCRPredictResult> OCRPredictResult = _engine->ocr(*image, true, true, FLAGS_cls);//auto end = std::chrono::steady_clock::now();//std::chrono::duration<double, std::milli> duration = end - start;//std::cout << "ocr识别耗时 : " << duration.count() << " ms" << std::endl;//返回json格式json array = json::array();
for (int i = 0; i < OCRPredictResult.size(); i++) {json texts = {};texts["text"] = OCRPredictResult[i].text;texts["score"] = OCRPredictResult[i].score;texts["x1"] = OCRPredictResult[i].box[0][0];texts["y1"] = OCRPredictResult[i].box[0][1];texts["x2"] = OCRPredictResult[i].box[1][0];texts["y2"] = OCRPredictResult[i].box[1][1];texts["x3"] = OCRPredictResult[i].box[2][0];texts["y3"] = OCRPredictResult[i].box[2][1];texts["x4"] = OCRPredictResult[i].box[3][0];texts["y4"] = OCRPredictResult[i].box[3][1];array.push_back(texts);}std::string json_str = array.dump();*ocr_result_len = (int)json_str.size();*ocr_result = (char*)CoTaskMemAlloc(*ocr_result_len + 1);strcpy_s(*ocr_result, *ocr_result_len + 1, json_str.c_str());strcpy_s(msg, 128, "ocr success");
return 0;
}//释放
int __cdecl destroy(void* engine, char* msg) {
if (engine != nullptr){PPOCR* _engine = (PPOCR*)engine;delete _engine;_engine = nullptr;strcpy_s(msg, 128, "destroy success");
return 0;}
else{strcpy_s(msg, 128, "engine is nullptr");
return -1;}
}//structure
int __cdecl structure_init(void** engine, int cpu_threads, bool enable_mkldnn, char* det_model_dir, int limit_side_len, double det_db_thresh, double det_db_box_thresh, double det_db_unclip_ratio, bool use_dilation, bool cls, bool use_angle_cls, char* cls_model_dir, double cls_thresh, double cls_batch_num, char* rec_model_dir, char* rec_char_dict_path, int rec_batch_num, int rec_img_h, int rec_img_w, int table_max_len, int table_batch_num, char* table_model_dir, char* table_char_dict_path, char* msg) {try {FLAGS_cpu_threads = cpu_threads;FLAGS_enable_mkldnn = enable_mkldnn;FLAGS_visualize = false;//det FLAGS_det_model_dir = det_model_dir;FLAGS_limit_side_len = limit_side_len;FLAGS_det_db_thresh = det_db_thresh;FLAGS_det_db_box_thresh = det_db_box_thresh;FLAGS_det_db_unclip_ratio = det_db_unclip_ratio;FLAGS_use_dilation = use_dilation;//clsFLAGS_cls = cls;FLAGS_use_angle_cls = use_angle_cls;FLAGS_cls_model_dir = cls_model_dir;FLAGS_cls_thresh = cls_thresh;FLAGS_cls_batch_num = cls_batch_num;//recFLAGS_rec_model_dir = rec_model_dir;FLAGS_rec_char_dict_path = rec_char_dict_path;FLAGS_rec_batch_num = rec_batch_num;FLAGS_rec_img_h = rec_img_h;FLAGS_rec_img_w = rec_img_w;FLAGS_table = true;FLAGS_table_model_dir = table_model_dir;FLAGS_table_char_dict_path = table_char_dict_path;FLAGS_table_max_len = table_max_len;FLAGS_table_batch_num = table_batch_num;PaddleStructure* _engine = new PaddleStructure();*engine = _engine;strcpy_s(msg, 128, "structure_init success");return 0;}catch (...) {std::cout << "structure_init error" << std::endl;strcpy_s(msg, 128, "structure_init error");
return -1;}
}//structure
int __cdecl structure(void* engine, Mat* image, char* msg, char** ocr_result, int* ocr_result_len) {if (engine == nullptr){strcpy_s(msg, 128, "structure engine is nullptr");
return -1;}PaddleStructure* _engine = (PaddleStructure*)engine;std::vector<StructurePredictResult> structure_results = _engine->structure(*image, FLAGS_layout, FLAGS_table, FLAGS_det && FLAGS_rec);json array = json::array();
for (size_t j = 0; j < structure_results.size(); ++j) {json structure = {};structure["type"] = structure_results[j].type;structure["x1"] = structure_results[j].box[0];structure["y1"] = structure_results[j].box[1];structure["x2"] = structure_results[j].box[2];structure["y2"] = structure_results[j].box[3];structure["confidence"] = structure_results[j].confidence;structure["res"] = structure_results[j].html;array.push_back(structure);}std::string json_str = array.dump();*ocr_result_len = (int)json_str.size();*ocr_result = (char*)CoTaskMemAlloc(*ocr_result_len + 1);strcpy_s(*ocr_result, *ocr_result_len + 1, json_str.c_str());strcpy_s(msg, 128, "structure success");
return 0;}//释放
int __cdecl structure_destroy(void* engine, char* msg) {
if (engine != nullptr){PaddleStructure* _engine = (PaddleStructure*)engine;delete _engine;_engine = nullptr;strcpy_s(msg, 128, "structure destroy success");
return 0;}
else{strcpy_s(msg, 128, "structure engine is nullptr");
return -1;}
}

C#调用

using Newtonsoft.Json;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;

namespace OCRV5Test
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        const string DllName = "lw.PPOCRSharp.dll";

        //初始化
        [DllImport(DllName, EntryPoint = "init", CallingConvention = CallingConvention.Cdecl)]
        public extern static int init(ref IntPtr engine
            , int cpu_threads
            , bool enable_mkldnn

            , string det_model_dir
            , int limit_side_len
            , double det_db_thresh
            , double det_db_box_thresh
            , double det_db_unclip_ratio
            , bool use_dilation

            , bool cls
            , bool use_angle_cls
            , string cls_model_dir
            , double cls_thresh
            , double cls_batch_num

            , string rec_model_dir
            , string rec_char_dict_path
            , int rec_batch_num
            , int rec_img_h
            , int rec_img_w

            , StringBuilder msg);

        //识别
        [DllImport(DllName, EntryPoint = "ocr", CallingConvention = CallingConvention.Cdecl)]
        public extern static int ocr(IntPtr engine, IntPtr image, StringBuilder msg, out IntPtr ocr_result, out int ocr_result_len);

        //释放
        [DllImport(DllName, EntryPoint = "destroy", CallingConvention = CallingConvention.Cdecl)]
        public extern static int destroy(IntPtr engine, StringBuilder msg);

        static IntPtr OCREngine;

        private Bitmap bmp;

        private String imgPath = null;

        private List<OCRResult> ltOCRResult;

        private string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tif;*.png";

        private StringBuilder OCRResultInfo = new StringBuilder();
        private StringBuilder OCRResultAllInfo = new StringBuilder();

        Pen pen = new Pen(Brushes.Red, 2f);

        private void button1_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = fileFilter;
            if (ofd.ShowDialog() == DialogResult.OK)
            {
                imgPath = ofd.FileName;
                bmp = new Bitmap(imgPath);
                pictureBox1.Image = bmp;
                richTextBox1.Clear();

                button2_Click(null, null);
            }
        }

        private void button2_Click(object sender, EventArgs e)
        {
            if (imgPath == null)
            {
                return;
            }
            button1.Enabled = false;
            button2.Enabled = false;
            richTextBox1.Clear();
            OCRResultInfo.Clear();
            OCRResultAllInfo.Clear();

            Application.DoEvents();
            Mat img = new Mat(imgPath);
            StringBuilder msgTemp = new StringBuilder(128);
            StringBuilder ocrResultStr = new StringBuilder(1024 * 100);

            Stopwatch stopwatch = new Stopwatch();
            stopwatch.Start();

            IntPtr strPtr;
            int ocr_result_len = 0;

            int res = ocr(OCREngine, img.CvPtr, msgTemp, out strPtr, out ocr_result_len);
            byte[] buffer = new byte[ocr_result_len];
            Marshal.Copy(strPtr, buffer, 0, ocr_result_len);
            string ocr_result = Encoding.UTF8.GetString(buffer);
            Marshal.FreeCoTaskMem(strPtr);
            stopwatch.Stop();
            double totalTime = stopwatch.Elapsed.TotalSeconds;

            OCRResultAllInfo.AppendLine($"耗时: {totalTime:F2}s");
            OCRResultAllInfo.AppendLine("---------------------------");

            OCRResultInfo.AppendLine($"耗时: {totalTime:F2}s");
            OCRResultInfo.AppendLine("---------------------------");

            if (res == 0)
            {

                ltOCRResult = Newtonsoft.Json.JsonConvert.DeserializeObject<List<OCRResult>>(ocr_result);
                OCRResultAllInfo.Append(JsonConvert.SerializeObject(ltOCRResult, Newtonsoft.Json.Formatting.Indented));
                Graphics graphics = Graphics.FromImage(bmp);

                foreach (OCRResult item in ltOCRResult)
                {
                    OCRResultInfo.AppendLine(item.text);
                    System.Drawing.Point[] pt = new System.Drawing.Point[] {
                              new System.Drawing.Point(item.x1, item.y1)
                            , new System.Drawing.Point(item.x2, item.y2)
                            , new System.Drawing.Point(item.x3, item.y3)
                            , new System.Drawing.Point(item.x4, item.y4)
                        };
                    graphics.DrawPolygon(pen, pt);
                }
                graphics.Dispose();

                if (checkBox1.Checked)
                {
                    richTextBox1.Text = OCRResultAllInfo.ToString();
                }
                else
                {
                    richTextBox1.Text = OCRResultInfo.ToString();
                }

                pictureBox1.Image = null;
                pictureBox1.Image = bmp;
            }
            else
            {
                MessageBox.Show("识别失败," + msgTemp.ToString());
            }

            img.Release();
            button1.Enabled = true;
            button2.Enabled = true;
        }

        /// <summary>
        /// 初始化
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void Form1_Load(object sender, EventArgs e)
        {
            radioButton1.Checked = true;
        }

        void LoadModel()
        {

            StringBuilder msgTemp = new StringBuilder(128);
            string root_dir = Application.StartupPath + @"\inference";

            int cpu_threads = 2 ;
            bool enable_mkldnn = true;

            string det_model_dir = "";
            int limit_side_len = 960;
            double det_db_thresh = 0.3;
            double det_db_box_thresh = 0.6;
            double det_db_unclip_ratio = 1.2;
            bool use_dilation = false;

            bool cls = false;
            bool use_angle_cls = true;
            string cls_model_dir = root_dir + @"\ch_ppocr_mobile_v2.0_cls_infer\";
            double cls_thresh = 0.9;
            int cls_batch_num = 1;

            string rec_model_dir = "";
            string rec_char_dict_path = root_dir + @"\ppocrv5_dict.txt";
            int rec_batch_num = 1;
            int rec_img_h = 48;
            int rec_img_w = 320;

            if (radioButton1.Checked)
            {
                det_model_dir = root_dir + @"\PP-OCRv5_mobile_det_infer\";
                rec_model_dir = root_dir + @"\PP-OCRv5_mobile_rec_infer\";
            }
            else
            {
                det_model_dir = root_dir + @"\PP-OCRv5_server_det_infer\";
                rec_model_dir = root_dir + @"\PP-OCRv5_server_rec_infer\";
            }
            int res = init(ref OCREngine
                        , cpu_threads
                        , enable_mkldnn

                        , det_model_dir
                        , limit_side_len
                        , det_db_thresh
                        , det_db_box_thresh
                        , det_db_unclip_ratio
                        , use_dilation

                        , cls
                        , use_angle_cls
                        , cls_model_dir
                        , cls_thresh
                        , cls_batch_num

                        , rec_model_dir
                        , rec_char_dict_path
                        , rec_batch_num
                        , rec_img_h
                        , rec_img_w

                        , msgTemp);

            if (res == 0)
            {
                MessageBox.Show("模型加载成功!");
            }
            else
            {
                string msg = msgTemp.ToString();
                MessageBox.Show("模型加载失败," + msg);
            }
        }

        private void checkBox1_CheckedChanged(object sender, EventArgs e)
        {
            richTextBox1.Clear();
            if (checkBox1.Checked)
            {
                richTextBox1.Text = OCRResultAllInfo.ToString();
            }
            else
            {
                richTextBox1.Text = OCRResultInfo.ToString();
            }
        }

        private void radioButton1_CheckedChanged(object sender, EventArgs e)
        {
            RadioButton rb = sender as RadioButton;
            if (rb != null && rb.Checked)
            {
                //MessageBox.Show("选中的是:" + rb.Text);
                LoadModel();
            }
        }

        private void Form1_FormClosing(object sender, FormClosingEventArgs e)
        {
            StringBuilder msgTemp = new StringBuilder(128);
            destroy(OCREngine, msgTemp);
        }
    }

}

using Newtonsoft.Json;
using OpenCvSharp;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Runtime.InteropServices;
using System.Text;
using System.Windows.Forms;namespace OCRV5Test
{public partial class Form1 : Form{public Form1(){InitializeComponent();}const string DllName = "lw.PPOCRSharp.dll";//初始化[DllImport(DllName, EntryPoint = "init", CallingConvention = CallingConvention.Cdecl)]public extern static int init(ref IntPtr engine, int cpu_threads, bool enable_mkldnn, string det_model_dir, int limit_side_len, double det_db_thresh, double det_db_box_thresh, double det_db_unclip_ratio, bool use_dilation, bool cls, bool use_angle_cls, string cls_model_dir, double cls_thresh, double cls_batch_num, string rec_model_dir, string rec_char_dict_path, int rec_batch_num, int rec_img_h, int rec_img_w, StringBuilder msg);//识别[DllImport(DllName, EntryPoint = "ocr", CallingConvention = CallingConvention.Cdecl)]public extern static int ocr(IntPtr engine, IntPtr image, StringBuilder msg, out IntPtr ocr_result, out int ocr_result_len);//释放[DllImport(DllName, EntryPoint = "destroy", CallingConvention = CallingConvention.Cdecl)]public extern static int destroy(IntPtr engine, StringBuilder msg);static IntPtr OCREngine;private Bitmap bmp;private String imgPath = null;private List<OCRResult> ltOCRResult;private string fileFilter = "*.*|*.bmp;*.jpg;*.jpeg;*.tiff;*.tif;*.png";private StringBuilder OCRResultInfo = new StringBuilder();private StringBuilder OCRResultAllInfo = new StringBuilder();Pen pen = new Pen(Brushes.Red, 2f);private void button1_Click(object sender, EventArgs e){OpenFileDialog ofd = new OpenFileDialog();ofd.Filter = fileFilter;if (ofd.ShowDialog() == DialogResult.OK){imgPath = ofd.FileName;bmp = new Bitmap(imgPath);pictureBox1.Image = bmp;richTextBox1.Clear();button2_Click(null, null);}}private void button2_Click(object sender, EventArgs e){if (imgPath == null){return;}button1.Enabled = false;button2.Enabled = false;richTextBox1.Clear();OCRResultInfo.Clear();OCRResultAllInfo.Clear();Application.DoEvents();Mat img = new Mat(imgPath);StringBuilder msgTemp = new StringBuilder(128);StringBuilder ocrResultStr = new StringBuilder(1024 * 100);Stopwatch stopwatch = new Stopwatch();stopwatch.Start();IntPtr strPtr;int ocr_result_len = 0;int res = ocr(OCREngine, img.CvPtr, msgTemp, out strPtr, out ocr_result_len);byte[] buffer = new byte[ocr_result_len];Marshal.Copy(strPtr, buffer, 0, ocr_result_len);string ocr_result = Encoding.UTF8.GetString(buffer);Marshal.FreeCoTaskMem(strPtr);stopwatch.Stop();double totalTime = stopwatch.Elapsed.TotalSeconds;OCRResultAllInfo.AppendLine($"耗时: {totalTime:F2}s");OCRResultAllInfo.AppendLine("---------------------------");OCRResultInfo.AppendLine($"耗时: {totalTime:F2}s");OCRResultInfo.AppendLine("---------------------------");if (res == 0){ltOCRResult = Newtonsoft.Json.JsonConvert.DeserializeObject<List<OCRResult>>(ocr_result);OCRResultAllInfo.Append(JsonConvert.SerializeObject(ltOCRResult, Newtonsoft.Json.Formatting.Indented));Graphics graphics = Graphics.FromImage(bmp);foreach (OCRResult item in ltOCRResult){OCRResultInfo.AppendLine(item.text);System.Drawing.Point[] pt = new System.Drawing.Point[] {new System.Drawing.Point(item.x1, item.y1), new System.Drawing.Point(item.x2, item.y2), new System.Drawing.Point(item.x3, item.y3), new System.Drawing.Point(item.x4, item.y4)};graphics.DrawPolygon(pen, pt);}graphics.Dispose();if (checkBox1.Checked){richTextBox1.Text = OCRResultAllInfo.ToString();}else{richTextBox1.Text = OCRResultInfo.ToString();}pictureBox1.Image = null;pictureBox1.Image = bmp;}else{MessageBox.Show("识别失败," + msgTemp.ToString());}img.Release();button1.Enabled = true;button2.Enabled = true;}/// <summary>/// 初始化/// </summary>/// <param name="sender"></param>/// <param name="e"></param>private void Form1_Load(object sender, EventArgs e){radioButton1.Checked = true;}void LoadModel(){StringBuilder msgTemp = new StringBuilder(128);string root_dir = Application.StartupPath + @"\inference";int cpu_threads = 2 ;bool enable_mkldnn = true;string det_model_dir = "";int limit_side_len = 960;double det_db_thresh = 0.3;double det_db_box_thresh = 0.6;double det_db_unclip_ratio = 1.2;bool use_dilation = false;bool cls = false;bool use_angle_cls = true;string cls_model_dir = root_dir + @"\ch_ppocr_mobile_v2.0_cls_infer\";double cls_thresh = 0.9;int cls_batch_num = 1;string rec_model_dir = "";string rec_char_dict_path = root_dir + @"\ppocrv5_dict.txt";int rec_batch_num = 1;int rec_img_h = 48;int rec_img_w = 320;if (radioButton1.Checked){det_model_dir = root_dir + @"\PP-OCRv5_mobile_det_infer\";rec_model_dir = root_dir + @"\PP-OCRv5_mobile_rec_infer\";}else{det_model_dir = root_dir + @"\PP-OCRv5_server_det_infer\";rec_model_dir = root_dir + @"\PP-OCRv5_server_rec_infer\";}int res = init(ref OCREngine, cpu_threads, enable_mkldnn, det_model_dir, limit_side_len, det_db_thresh, det_db_box_thresh, det_db_unclip_ratio, use_dilation, cls, use_angle_cls, cls_model_dir, cls_thresh, cls_batch_num, rec_model_dir, rec_char_dict_path, rec_batch_num, rec_img_h, rec_img_w, msgTemp);if (res == 0){MessageBox.Show("模型加载成功!");}else{string msg = msgTemp.ToString();MessageBox.Show("模型加载失败," + msg);}}private void checkBox1_CheckedChanged(object sender, EventArgs e){richTextBox1.Clear();if (checkBox1.Checked){richTextBox1.Text = OCRResultAllInfo.ToString();}else{richTextBox1.Text = OCRResultInfo.ToString();}}private void radioButton1_CheckedChanged(object sender, EventArgs e){RadioButton rb = sender as RadioButton;if (rb != null && rb.Checked){//MessageBox.Show("选中的是:" + rb.Text);LoadModel();}}private void Form1_FormClosing(object sender, FormClosingEventArgs e){StringBuilder msgTemp = new StringBuilder(128);destroy(OCREngine, msgTemp);}}}

下载

 https://download.csdn.net/download/lw112190/90909238

或者

PP-OCRv5 Test C#调用完整项目源码.rar
链接: https://pan.baidu.com/s/10wU15EkkxFy7wxxmsi61EQ?pwd=n79z 提取码: n79z


http://www.hkcw.cn/article/mYqEERjZqj.shtml

相关文章

RISC-V PMA、PMP机制深入分析

1 PMA PMA&#xff08;Physical Memory Attributes&#xff09;&#xff0c;物理内存属性&#xff0c;顾名思义就是用来设置物理内存属性的&#xff0c;但这里说“设置”&#xff0c;并不合理&#xff0c;因为一般情况下各存储的属性&#xff0c;在芯片设计时就固定了&#xf…

桂花网体育运动监测方案:开启幼儿园运动健康管理新篇章

在幼儿教育领域&#xff0c;运动能力的培养与健康监测始终是备受关注的核心环节。随着科技的飞速发展&#xff0c;如何科学、有效地监测幼儿的运动状态&#xff0c;成为了幼儿园教育者面临的一大挑战。桂花网体育运动监测方案凭借其高效、精准、智能化的特性&#xff0c;为幼儿…

第6讲、 Odoo 18 `tools` 模块深度分析

Odoo 18 中的 odoo/tools 目录是核心工具模块的集合&#xff0c;封装了大量通用功能&#xff0c;包括数据处理、安全校验、缓存优化、文件处理、时间转换、国际化、多线程处理等。这些工具模块在整个 Odoo 框架中被频繁引用&#xff0c;是系统高效运行和代码解耦的重要基础。 &…

如何在矩池云实例上开启应用服务的访问端口

AI 应用开发越来越火热&#xff0c;矩池云平台上也相应出现了越来越多的 AI 应用开发者&#xff0c;这里详细介绍下大家在使用过程中经常遇到的一个问题&#xff1a;在矩池云的实例上&#xff0c;如何为应用服务开启外部可访问的端口&#xff1f; 根据开发者有没有启动实例&…

首发支持! 基于昇腾MindIE玩转InternVL3多模态理解最新模型

2025年4月16日&#xff0c;上海人工智能实验室&#xff08;上海AI实验室&#xff09;升级并开源了通用多模态大模型书生万象3.0&#xff08;InternVL3&#xff09;。通过采用创新的多模态预训练和后训练方法&#xff0c;InternVL3 多模态基础能力全面提升&#xff0c;在专家级基…

深入解析Java8核心新特性(Optional、新的日期时间API、接口增强)

文章目录 前言一、Optional&#xff1a;优雅处理null1.1 Optional设计哲学1.2 Optional基础操作1.3 Optional链式操作1.4 高级应用1.5 Optional实战案例 二、新的日期时间API&#xff1a;解决历史痛点2.1 java.time 设计哲学与核心架构2.2 核心类详解与使用基本日期时间类时区相…

深入理解C#中的委托与事件:从基础到高级应用

在C#编程语言中&#xff0c;委托和事件是两个强大且独特的特性&#xff0c;它们为方法封装、回调机制和事件驱动编程提供了语言级别的支持。作为.NET框架的核心组件&#xff0c;委托和事件广泛应用于Windows Forms、WPF、ASP.NET等各类应用程序中。本文将全面探讨委托与事件的概…

设备制造行业项目管理难点解析,如何有效解决?

在设备制造行业&#xff0c;项目管理是企业运营的核心环节&#xff0c;直接影响项目交付效率、成本控制和盈利能力。然而&#xff0c;由于行业特性复杂、项目周期长、涉及部门多&#xff0c;企业在实际操作中常常面临诸多管理痛点。金众诚工程项目管理系统&#xff0c;依托金蝶…

如何应对客户对项目进度的过度干预

当客户对项目进度进行过度干预时&#xff0c;企业应采取明确项目边界、建立透明沟通机制、提升客户信任感、提供详实进度报告等措施。其中&#xff0c;明确项目边界尤为关键&#xff0c;它能有效帮助企业和客户共同确认项目的权责范围&#xff0c;防止客户的过度干预影响项目整…

11:QT界面设计—模态UI对话框

1.模态UI对话框 1.创建dialog的界面模板 2.进行模板界面设计 3.在主程序调用此界面 需要包含此类和实例化此类&#xff0c;然后调用下面的程序m_pShapeMatch->setModal(false); //如果改为true&#xff0c;则弹出对话框之后无法进行其它操作m_pShapeMatch->show(); 2.…

重温经典算法——选择排序

版权声明 本文原创作者&#xff1a;谷哥的小弟作者博客地址&#xff1a;http://blog.csdn.net/lfdfhl 基本原理 选择排序属于简单的原地排序算法&#xff0c;通过将待排序序列分为已排序和未排序两部分&#xff0c;每次从未排序部分选择最小元素&#xff0c;与未排序部分的起…

RFID测温芯片助力新能源产业安全与能效提升

在“双碳”目标驱动下&#xff0c;新能源产业正经历爆发式增长。无论是电动汽车、储能电站还是风光发电场&#xff0c;设备安全与能效提升始终是行业核心命题。而温度&#xff0c;这个看似普通的物理参数&#xff0c;却成为破解这一命题的关键密码。RFID测温芯片&#xff08;集…

数据的类型——认识你的数据

第02篇&#xff1a;数据的类型——认识你的数据 写在前面&#xff1a;嗨&#xff0c;大家好&#xff01;我是蓝皮怪。在上一篇文章中&#xff0c;我们聊了统计学的基本概念&#xff0c;今天我们来深入了解一个非常重要的话题——数据的类型。你可能会想&#xff1a;"数据就…

【JVM】初识JVM 从字节码文件到类的生命周期

初识JVM JVM&#xff08;Java Virtual Machine&#xff09;即 Java 虚拟机&#xff0c;是 Java 技术的核心组件之一。JVM的本质就是运行在计算机上的一个程序&#xff0c;通过软件模拟实现了一台抽象的计算机的功能。JVM是Java程序的运行环境&#xff0c;负责加载字节码文件&a…

WebVm:无需安装,一款可以在浏览器运行的 Linux 来了

WebVM 是一款可以在浏览器中运行的Linux虚拟机。不是那种HTMLJavaScript模拟的UI&#xff0c;完全通过HTML5/WebAssembly技术实现客户端运行。通过集成CheerpX虚拟化引擎&#xff0c;可直接在浏览器中运行未经修改的Debian系统。 Stars 数13054Forks 数2398 主要特点 完整 Lin…

动态规划-931.下降路径最小和-力扣(LeetCode)

一、题目解析 从最顶上出发&#xff0c;有三个位置选择&#xff0c;左中下(边界除外)&#xff0c;使其走到最下面时下降路径最小。 二、算法原理 1、状态表示 我们需要的是到达[i,j]的最小路径和&#xff0c;所以此时dp[i][j]表示&#xff1a;到达[i,j]位置时&#xff0c;最…

ssm学习笔记(尚硅谷) day1

创建新项目 maven的聚合 1. 标记父类项目 标签<packaging>pom</packaging>表示将该项目标记为父类项目&#xff0c;必须添加。 以下是标签<packing>的常见取值 groupId在pom.xml中&#xff0c;可以从pom.xml直接修改。 2. 通过<modules>添加子项目…

数据库 | 时序数据库选型

选型目标 高性能与低延迟&#xff1a;满足高频率数据写入与即时查询的需求。资源效率&#xff1a;优化存储空间使用&#xff0c;减少计算资源消耗。可扩展架构&#xff1a;支持数据量增长带来的扩展需求&#xff0c;易于维护。社区活跃度&#xff1a;有活跃的开发者社区&#…

Linux | Shell脚本的基础知识

一. 定义 1.1 什么是shell脚本 shell脚本是一种可运行的文本shell脚本的内容是由逻辑和数据组成shell脚本是解释型语言 命令不可单独执行&#xff0c;由解释器将代码转换为系统指令&#xff0c;系统接受指令后执行速度比编译型语言慢&#xff0c;优点是简单&#xff0c;开发效…

Window Server 2019--09 路由和桥接的设置

本章要点 >>了解路由器工作原理。 >>掌握路由与远程访问服务的设置。 >>掌握桥接的设置。 路由器(Router)是网络中的核心设备&#xff0c;它工作在开放系统互连(Open SystemInter- connection&#xff0c;OSI)网络参考模型的网络层(第3层),用于连接多个在…