使用MSR605X时触发SystemAccessViolation异常问题求助
Deftun MSR605X 调用MagAPI.dll初始化时触发AccessViolation异常(返回码-36)
问题详情
开发Windows Forms应用读写Deftun MSR605X磁条卡数据,设备自带MSRX程序可正常运行,但自行调用配套MagAPI.dll时遇到以下问题:
- 调用
MSR_InitComm(vendorId, productId)初始化通信时触发System.AccessViolationException,函数返回值为-36(官方文档、网络搜索均未找到该返回码含义) - 即使使用
try-catch捕获异常,程序仍直接崩溃,无法执行到异常提示逻辑 - 设备已通过USB正常连接,但初始化始终失败
当前代码:
using System; using System.Windows.Forms; using System.Runtime.InteropServices; namespace CardReaderApp { public partial class Form1 : Form { private IntPtr handle; public Form1() { InitializeComponent(); } private void Form1_Load(object sender, EventArgs e) { int vendorId = 0x0801; int productId = 0x0003; try { handle = MSR_InitComm(vendorId, productId); } catch (System.AccessViolationException ex) { MessageBox.Show("Access violation error: " + ex.Message); } if (handle != IntPtr.Zero) { textBox1.Text = "MSR605X connected\r\n"; } else { textBox1.Text = "Failed to connect to MSR605X\r\n"; } } protected override void OnFormClosing(FormClosingEventArgs e) { if (handle != IntPtr.Zero) { MSR_ExitComm(handle); } base.OnFormClosing(e); } private void ReadData() { byte[] data = new byte[1024]; int length = MSR_Read(handle, data, data.Length); } [DllImport("MagAPI.dll", EntryPoint = "MSR_InitComm", CallingConvention = CallingConvention.StdCall)] private static extern IntPtr MSR_InitComm(int vendorId, int productId); [DllImport("MagAPI.dll", EntryPoint = "MSR_ExitComm", CallingConvention = CallingConvention.StdCall)] private static extern void MSR_ExitComm(IntPtr handle); [DllImport("MagAPI.dll", EntryPoint = "MSR_Read", CallingConvention = CallingConvention.StdCall)] private static extern int MSR_Read(IntPtr handle, byte[] data, int length); } }
可能的原因及修复方案
1. P/Invoke函数签名不匹配
AccessViolation异常通常源于托管代码与非托管DLL的函数签名不兼容,重点检查MSR_InitComm的返回值和参数类型:
- 部分版本的MagAPI.dll中,
MSR_InitComm的返回值为int(0表示成功,负数为错误码),设备句柄通过输出参数传递而非返回值。修正签名及调用方式:// 修正后的函数签名 [DllImport("MagAPI.dll", EntryPoint = "MSR_InitComm", CallingConvention = CallingConvention.StdCall)] private static extern int MSR_InitComm(int vendorId, int productId, out IntPtr handle); // 调用逻辑修改 int result = MSR_InitComm(vendorId, productId, out handle); if (result == 0) { textBox1.Text = "MSR605X connected\r\n"; } else { textBox1.Text = $"Failed to connect, error code: {result}\r\n"; }
2. 平台目标不匹配
MagAPI.dll通常分32位和64位版本,若项目平台目标设为Any CPU,易出现位数不兼容问题:
- 在项目属性中,将平台目标改为
x86(多数MSR605X配套DLL为32位) - 确保项目输出目录中放置对应位数的MagAPI.dll
3. 程序权限不足
USB设备通信需要足够系统权限:
- 右键以管理员身份运行程序,测试是否能正常初始化
- 若问题解决,可在项目中添加应用程序清单,设置
requestedExecutionLevel为requireAdministrator
4. 设备被其他进程占用
即使关闭自带MSRX程序,仍可能存在残留进程占用设备:
- 打开任务管理器,结束所有与MSRX相关的进程
- 重新插拔设备后再测试程序
5. 捕获非托管异常
AccessViolation属于非托管异常,默认try-catch无法捕获,需开启非托管异常捕获:
- 在
Program.cs的Main方法中添加配置:
注:此方式仅用于调试排查,生产环境需谨慎使用[HandleProcessCorruptedStateExceptions] [SecurityCritical] static void Main() { Application.EnableVisualStyles(); Application.SetCompatibleTextRenderingDefault(false); Application.Run(new Form1()); }
内容的提问来源于stack exchange,提问作者Bellator
相关产品推荐
相关产品推荐

