C# 調用OpenCVSharp報錯“嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞”

来源:https://www.cnblogs.com/cherish836138981/archive/2019/12/05/11987954.html
-Advertisement-
Play Games

一、描述問題 當托管代碼調用非托管代碼的時候,經常會出現如下報錯:“嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞”。 二、原因分析 由於非托管代碼的記憶體指針的回收是由非托管代碼自身手動完成的,而不是像托管代碼一樣有統一的垃圾回收機制,比如.NET的GC。 所以對於托管代碼的調用方來說無法控制 ...


一、描述問題

當托管代碼調用非托管代碼的時候,經常會出現如下報錯:“嘗試讀取或寫入受保護的記憶體。這通常指示其他記憶體已損壞”。

二、原因分析

由於非托管代碼的記憶體指針的回收是由非托管代碼自身手動完成的,而不是像托管代碼一樣有統一的垃圾回收機制,比如.NET的GC。

所以對於托管代碼的調用方來說無法控制其記憶體回收。以上問題的產生原因很可能是托管代碼調用了已經被回收的非托管對象。封裝

的好一點的非托管代碼一般都會有記憶體釋放的介面供外部調用,這樣調用方就可以管理非托管代碼的記憶體回收。

三、解決方法

儘量不用使用不確定的非托管代碼裡面提供的對象。如果必須使用的話,實例化完成後直接使用而不要通過什麼方法傳遞,委托回調等方式來

獲取裡面的對象,在這些複雜未知的過程中,很可能非托管的對象已經被回收了。

四、示例說明

當使用C#調用OpenCVSharp的時候,經常會出現以上問題。

錯誤代碼如下:

1、訂閱滑鼠回調方法,並將mat的指針Data作為參數傳遞給回調方法。

1   private void button15_Click(object sender, EventArgs e)
2         {
3             Mat mat = GetMat();//獲取Mat對象
4             Cv2.SetMouseCallback("輸入圖像", GetRGBCvMouseCallback, mat.Data);
5         }

2、回調方法,獲取每個點的RGB值

 1   private void GetRGBCallbackMethod(MouseEvent @event, int x, int y, MouseEvent flags, IntPtr userdata)
 2         {
 3             switch (@event)
 4             {
 5                 case MouseEvent.LButtonDown:
 6 
 7                     using (Mat mat = new Mat(Rows, Cols, _MatType, userdata))//這種方式會被記憶體回收,直接在這裡面獲取對象
 8                     {
 9                         for (int i = 0; i < Rows; i++)
10                         {
11                             for (int j = 0; j < Cols; j++)
12                             {
13                                 Vec3b s = mat.At<Vec3b>(j, i);//獲取第i0行第i1列)  這個方法會死 嘗試讀取收保護記憶體
14                             }
15 
16                         }
17                     }
18                     break;
19                 default:
20                     break;
21            }

運行報錯,截圖如下:

 

 

正確代碼:

   將7行代碼Mat mat = new Mat(Rows, Cols, _MatType, userdata)改成using (Mat mat=GetMat()) ,就不會出現以上問題。

原因分析:

原因很可能是userData中回調的過程中已經被回收了,當再次使用時就會報嘗試訪問被保護的記憶體的錯誤。為了

防止此問題的發生,解決辦法就是重新實例化一個Mat對象,不使用可能被回收的userData數據。

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • AMP(加速的移動頁面)是Google的開發人員軟體包,它允許開發負載更快的輕量級系統。AMP是由HTML,JavaScript和CSS組成的框架,它們是為用戶提供Web內容優先格式的標準。 Aspose.Email for .NET是一套全面的電子郵件處理API,可用於構建跨平臺應用程式。近期的更 ...
  • 1、先創建 .net core Web 應用程式,選擇API 2、安裝 Nuget 包:Nlog.Web.AspNetCore install-package Nlog install-package Nlog.Web.AspNetCore 或者打開Nuget管理界面搜索Nlog.Web.AspNe ...
  • 什麼是過濾器? 過濾器的類型與作用 定義過濾器 授權過濾器 動作過濾器 結果過濾器 異常處理過濾器 過濾器的使用方法 總結 什麼是過濾器? 通過上一篇關於Controller控制器的文章我們知道,MVC中的每一個請求,都會分配給相應的控制器(Controller)和對應的行為方法(Action)去處 ...
  • 本筆記摘抄自:https://www.cnblogs.com/zhili/archive/2012/07/20/MultiThreads.html,記錄一下學習過程以備後續查用。 一、I/O線程實現對文件的非同步 1.1 I/O線程介紹: 對於線程所執行的任務來說,可以把線程分為兩種類型:工作者線程和 ...
  • 基於Task的非同步編程模式(TAP)是Microsoft為.Net平臺下使用Task進行編程所提供的一組建議,這種模式提供了可以被await消耗(調用)方法的APIs,並且當使用async關鍵字編寫遵守這種模式的方法時,手寫Task通常很有用。通常TAP用起來與普通方式沒什麼兩樣,但是不支持ref和 ...
  • 概述 Spire.Cloud.Word提供了watermarksApi介面可用於添加水印,包括添加文本水印(SetTextWatermark)、圖片水印(SetImageWatermark),本文將對此做詳細介紹。 關於Spire.Cloud Spire.Cloud是雲端 Office 文檔處理軟體 ...
  • 它可以將字串內的字元替換為別的字元,可以嵌套使用,如下: 需要註意的是,它可以把字元替換為空,但不可以替換空字元,當不確定字元串是否為空時,可以進行以下判斷,再替換: 示例的完整代碼: string aa="d"; if (aa=="d") { Console.WriteLine(aa.Replac ...
  • 我有2個方法 代碼相同 都是執行上傳文件IO操作 一個同步 一個非同步 接著我用POSTMAN 分別用200個線程 去同時測試2個介面 結果很意外 2個介面 同時執行完成的速度 非同步更慢 之前經常看別人博主說 儘量用非同步來優化自己的代碼 但是經過自己測試後 發現使用非同步的效率結果更差,後面仔細想了下 ...
一周排行
    -Advertisement-
    Play Games
  • 概述:在C#中,++i和i++都是自增運算符,其中++i先增加值再返回,而i++先返回值再增加。應用場景根據需求選擇,首碼適合先增後用,尾碼適合先用後增。詳細示例提供清晰的代碼演示這兩者的操作時機和實際應用。 在C#中,++i 和 i++ 都是自增運算符,但它們在操作上有細微的差異,主要體現在操作的 ...
  • 上次發佈了:Taurus.MVC 性能壓力測試(ap 壓測 和 linux 下wrk 壓測):.NET Core 版本,今天計劃準備壓測一下 .NET 版本,來測試並記錄一下 Taurus.MVC 框架在 .NET 版本的性能,以便後續持續優化改進。 為了方便對比,本文章的電腦環境和測試思路,儘量和... ...
  • .NET WebAPI作為一種構建RESTful服務的強大工具,為開發者提供了便捷的方式來定義、處理HTTP請求並返迴響應。在設計API介面時,正確地接收和解析客戶端發送的數據至關重要。.NET WebAPI提供了一系列特性,如[FromRoute]、[FromQuery]和[FromBody],用 ...
  • 原因:我之所以想做這個項目,是因為在之前查找關於C#/WPF相關資料時,我發現講解圖像濾鏡的資源非常稀缺。此外,我註意到許多現有的開源庫主要基於CPU進行圖像渲染。這種方式在處理大量圖像時,會導致CPU的渲染負擔過重。因此,我將在下文中介紹如何通過GPU渲染來有效實現圖像的各種濾鏡效果。 生成的效果 ...
  • 引言 上一章我們介紹了在xUnit單元測試中用xUnit.DependencyInject來使用依賴註入,上一章我們的Sample.Repository倉儲層有一個批量註入的介面沒有做單元測試,今天用這個示例來演示一下如何用Bogus創建模擬數據 ,和 EFCore 的種子數據生成 Bogus 的優 ...
  • 一、前言 在自己的項目中,涉及到實時心率曲線的繪製,項目上的曲線繪製,一般很難找到能直接用的第三方庫,而且有些還是定製化的功能,所以還是自己繪製比較方便。很多人一聽到自己畫就害怕,感覺很難,今天就分享一個完整的實時心率數據繪製心率曲線圖的例子;之前的博客也分享給DrawingVisual繪製曲線的方 ...
  • 如果你在自定義的 Main 方法中直接使用 App 類並啟動應用程式,但發現 App.xaml 中定義的資源沒有被正確載入,那麼問題可能在於如何正確配置 App.xaml 與你的 App 類的交互。 確保 App.xaml 文件中的 x:Class 屬性正確指向你的 App 類。這樣,當你創建 Ap ...
  • 一:背景 1. 講故事 上個月有個朋友在微信上找到我,說他們的軟體在客戶那邊隔幾天就要崩潰一次,一直都沒有找到原因,讓我幫忙看下怎麼回事,確實工控類的軟體環境複雜難搞,朋友手上有一個崩潰的dump,剛好丟給我來分析一下。 二:WinDbg分析 1. 程式為什麼會崩潰 windbg 有一個厲害之處在於 ...
  • 前言 .NET生態中有許多依賴註入容器。在大多數情況下,微軟提供的內置容器在易用性和性能方面都非常優秀。外加ASP.NET Core預設使用內置容器,使用很方便。 但是筆者在使用中一直有一個頭疼的問題:服務工廠無法提供請求的服務類型相關的信息。這在一般情況下並沒有影響,但是內置容器支持註冊開放泛型服 ...
  • 一、前言 在項目開發過程中,DataGrid是經常使用到的一個數據展示控制項,而通常表格的最後一列是作為操作列存在,比如會有編輯、刪除等功能按鈕。但WPF的原始DataGrid中,預設只支持固定左側列,這跟大家習慣性操作列放最後不符,今天就來介紹一種簡單的方式實現固定右側列。(這裡的實現方式參考的大佬 ...