详细信息
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()
解决办法
- 问题&解决
出在对齐方式上:
[DllImport("ucrtbase.dll", CallingConvention=CallingConvention.Cdecl)]
| Cdecl | 2 | 调用方清理堆栈。 这使你能够调用具有 varargs 的函数(如 Printf),使之可用于接受可变数目的参数的方法。 |
|---|---|---|
| FastCall | 5 | 不支持此调用约定。 |
| StdCall | 3 | 被调用方清理堆栈。 |
| ThisCall | 4 | 第一个参数是 this 指针,它存储在寄存器 ECX 中。 其他参数被推送到堆栈上。 此调用约定用于对从非托管 DLL 导出的类调用方法。 |
| Winapi | 1 | 此成员实际上不是调用约定,而是使用 默认的平台调用约定。 |
参考:
非托管调用约定 - .NET | Microsoft Learn
CallingConvention 枚举 (System.Runtime.InteropServices) | Microsoft Learn