尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

309 阅读1分钟

详细信息

c# p/invoke c/c++的dll时出错:

System.AccessViolationException
  HResult=0x80004003
  Message=尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
  Source=GSK980TDi
  StackTrace:
   在 GSK980TDi.Gsk980tdi.Init() 在 F:\workspace\svn\products\2022\CAXADNCMonitor_Hanging\GSK980TDi\Gsk980tdi.cs 中: 第 85 行
   在 GSK980TDi.Gsk980tdi.Connect() 在 F:\workspace\svn\products\2022\CAXADNCMonitor_Hanging\GSK980TDi\Gsk980tdi.cs 中: 第 54 行
   在 GSK980TDi.MonitorGsk980tdi.Connect() 在 F:\workspace\svn\products\2022\CAXADNCMonitor_Hanging\GSK980TDi\MonitorGsk980tdi.cs 中: 第 94 行
   在 CXDataOperation.MonitorMng.GSK980TDiMonitor(String id, String name, String ip, String port, String type, String mac, Int32 p, Int32 id1, Int32 id2) 在 F:\workspace\svn\products\2022\CAXADNCMonitor_Hanging\CXFrame\MonitorMng.cs 中: 第 4123 行
   在 CXDataOperation.MonitorMng.<>c__DisplayClass119_0.<StartGSK980TDiThead>b__0() 在 F:\workspace\svn\products\2022\CAXADNCMonitor_Hanging\CXFrame\MonitorMng.cs 中: 第 4089 行
   在 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
   在 System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   在 System.Threading.ThreadHelper.ThreadStart()

解决办法

  1. 问题&解决

出在对齐方式上:

[DllImport("ucrtbase.dll", CallingConvention=CallingConvention.Cdecl)]
Cdecl2调用方清理堆栈。 这使你能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。
FastCall5不支持此调用约定。
StdCall3被调用方清理堆栈。
ThisCall4第一个参数是 this 指针,它存储在寄存器 ECX 中。 其他参数被推送到堆栈上。 此调用约定用于对从非托管 DLL 导出的类调用方法。
Winapi1此成员实际上不是调用约定,而是使用 默认的平台调用约定

参考:

非托管调用约定 - .NET | Microsoft Learn

CallingConvention 枚举 (System.Runtime.InteropServices) | Microsoft Learn