You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 03:42:04