0

I was trying to update data through Textbox when click on the button the AccessViolationException throws out at random everytime I click on the button to execute some funtions Not just that,while executing the program,the application crash without throwing any exceptions(it happens at random too,and if I click on the button twice quickly,the application would crash 100%) What cause these problems and how to fix them?

xaml:

<Button Content="读取软件版本号" Command ="{Binding ReadSoftwareVersion}">
<Button Content="写入板号"  Command ="{Binding WriteMcuSNCommand}"/>
<Button Content="读取板号"  Command ="{Binding ReadMcuSNCommand}"/>
<TextBox Text="{Binding StrSW}" />
<TextBox Text="{Binding StrMCUSN}" />
<TextBox Text="{Binding StrWrite}" />

three Commands:

private RelayCommand readSoftwareVersion;
public RelayCommand ReadSoftwareVersion
{
    get
    {
        readSoftwareVersion = new RelayCommand(ReadSW);
        return readSoftwareVersion;
    }
}

private RelayCommand writeMcuSNCommand;
public RelayCommand WriteMcuSNCommand
{
    get
    {
        writeMcuSNCommand = new RelayCommand(WriteMcuSN);
        return writeMcuSNCommand;
    }
}

private RelayCommand readMcuSNCommand;
public RelayCommand ReadMcuSNCommand
{
    get
    {
        readMcuSNCommand = new RelayCommand(ReadMcuSN);
        return readMcuSNCommand;
    }
}

And three functions:

private void WriteMcuSN()
{

        McuProtocolApi.funMcuRegister(int.Parse(Info.UartCom.Substring(3)), int.Parse(Info.UartBaud));
        byte[] NumberToWrite = new byte[11];
        NumberToWrite = System.Text.Encoding.Default.GetBytes(StrWrite);
        McuProtocolApi.funMcuWriteNumber(NumberToWrite, 10);
        McuProtocolApi.funMcuRelease();
}

private void ReadMcuSN()
{
        McuProtocolApi.funMcuRegister(int.Parse(Info.UartCom.Substring(3)), int.Parse(Info.UartBaud));
        page = (byte)129;
        byte[] McuSN = new byte[10];
        McuProtocolApi.funMcuReadNumber(bank, page, McuSN, 10);
        McuProtocolApi.funMcuRelease();
        StrMCUSN = Encoding.Default.GetString(McuSN);

}

private void ReadSW()
{
        page = (byte)128;
        byte[] SoftwareVersion = new byte[12];
        McuProtocolApi.funMcuReadEEprom(bank, page, SoftwareVersion, 12);
        McuProtocolApi.funMcuRelease();
        StrSW = Encoding.Default.GetString(SoftwareVersion);

}

the McuProtocol is a DLL code in C++ and the declarations are:

   [DllImport("McuProtocol.dll")]
    public static extern int funMcuReadEEprom(byte bank, byte page, byte[] EEprom, int DataSize);

    [DllImport("McuProtocol.dll")]
    public static extern int funMcuReadNumber(byte bank, byte page, byte[] EEprom, int DataSize);

    [DllImport("McuProtocol.dll")]
    public static extern int funMcuWriteNumber(byte[] in_data, int DataSize);

P.S.:I don't think these two functions below are relevant,

[DllImport("McuProtocol.dll")]
public static extern int funMcuRegister(int UartNum, int Baudrate); //this function opens a comport for transport bytes

[DllImport("McuProtocol.dll")]
public static extern int funMcuRelease();//this function releases comports

Edit:

I have optimized my code by replacing byte[] to IntPtr and the problems(both application crash and exception)still exist:

    private void ReadSW()
    {
        page = (byte)128;
        string TransferStr = "";
        IntPtr SoftwareVersion;
        SoftwareVersion = Marshal.StringToCoTaskMemAuto(TransferStr);

        McuProtocolApi.funMcuRegister(int.Parse(Info.UartCom.Substring(3)), int.Parse(Info.UartBaud));
        McuProtocolApi.funMcuReadEEprom(bank, page, SoftwareVersion, SoftwareVersionSize);
        McuProtocolApi.funMcuRelease();

        byte[] transfer = new byte[12];
        transfer = System.Text.Encoding.Unicode.GetBytes(Marshal.PtrToStringAuto(SoftwareVersion,SoftwareVersionSize/2));
        TransferStr = System.Text.Encoding.UTF8.GetString(transfer);

        StrSW = TransferStr;

    }
Bruno Wang
  • 23
  • 6

1 Answers1

0

AccessViolationException is thrown when there is an attempt to read or write protected memory. You should be very careful when you trying to use a 3rd party C++ DLL. Hence, I would recommend you to put some try-catch clause around these three Commands that you implemented.

Here are some helpful links: How to handle AccessViolationException

https://learn.microsoft.com/en-us/dotnet/api/system.accessviolationexception?view=net-6.0

Edit: If you find that it is hard to catch the exception, try this: Step #1 - Add following snippet to config file

<configuration>
   <runtime>
      <legacyCorruptedStateExceptionsPolicy enabled="true" />
   </runtime>
</configuration>

Step #2

Add

[HandleProcessCorruptedStateExceptions]
[SecurityCritical]

on the top of function you are tying catch the exception

(credit of EvilInside, How to handle AccessViolationException)

Haiming
  • 46
  • 4