libnodave - System.AccessViolationException

Ogoku

Level-1
Beiträge
18
Reaktionspunkte
1
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,


ich verwende in einem C# Windows-Forms Projekt, dass ich mit Visual Studio 2015 erstelle, libnodave.
die libnodave.dll kann man ja nicht direkt als Verweis einbinden, da muss ich ja libnodave.net.dll einbinden und dann noch libnodave.cs einfügen.
Soweit läuft auch alles.


Mittels einem Timer_Tick, lese und schreibe ich Werte zur SPS. Minimiere ich die Anwendung oder gehe in ein anderes Fenster (WindowState == FormWindowState.Minimized || Form.ActiveForm == null) bricht das Programm ab und bekomme den Fehler:


"System.AccessViolationException"


Dabei wird im Editor die Zeile 423 der libnodave.cs markiert: return daveGetU8(pointer);




Als erste Maßnahme habe ich im Tick eine Abfrage eingebaut, dass wenn das Fenster nicht aktiv oder minimiert wird, sich die Verbindung abbaut und nicht mehr gelese oder geschrieben wird. Der Fehler tritt jedoch wieder auf, sobald ich das Fenster wieder in den Vordergrund hole.




Wie kann ich diesen Fehler beheben?
Würde mich über Hilfe freuen.


Mit freundlichen Grüßen
Ogoku

EDIT:
Zusätzlich bekomme ich in der Konsole noch folgende Ausgabe:
"MPP483IE.vshost.exe" (CLR v4.0.30319: MPP483IE.vshost.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\mscorlib.resources\v4.0_4.0.0.0_de_b77a5c561934e089\mscorlib.resources.dll" geladen. Das Modul wurde ohne Symbole erstellt.
Ausnahme ausgelöst: "System.AccessViolationException" in MPP483IE.exe
"MPP483IE.vshost.exe" (CLR v4.0.30319: MPP483IE.vshost.exe): "C:\Windows\Microsoft.Net\assembly\GAC_MSIL\System.Configuration\v4.0_4.0.0.0__b03f5f7f11d50a3a\System.Configuration.dll" geladen. PDB-Datei wurde nicht gefunden oder konnte nicht geöffnet werden.
 
Zuletzt bearbeitet:
Dazu müsste du schon den kompletten Code deiner eigenen Anwendung zeigen. Du kannst dir so gut wie sicher sein, dass der Fehler nicht im libnodave-Teil liegt, sondern darin wie du die Schnittstelle handhabst, d.h. wo du die Ressourcen zur Verwendung von libnodave anlegst.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo,


hier der Code:


Code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;


namespace MPP483IE
{
    public partial class MPP483IE_Layout : Form
    {
        public static connector s7c = new connector();


        public class connector
        {
            public string ipAdress = "192.168.214.1";
            public int standardDB = 483;
            public bool error = true;
            public bool connected = false;
            public bool updating = false;


            public int[,] db = new int[80, 8];


            public states state = new states();
            public state_mask stateMask = new state_mask();


            public class states
            {
                public bool connection = true;
                public bool lifebit = false;
            }


            public class state_mask
            {
                public byte CONNECTION = 0x1;
                public byte LIFEBIT = 0x2;
                public byte RESET = 0x4;
            }


            static libnodave.daveOSserialType serialType;
            static libnodave.daveInterface iFace;
            public libnodave.daveConnection connection;
            static int rack = 0;
            static int slot = 2;


            public void close ()
            {
                connection.disconnectPLC();


                libnodave.closeSocket(serialType.rfd);
            }


            public byte get_byte(int _byteDB)
            {
                int _byte = 0;


                for (var _i = 0; _i < 8; _i++)
                {
                    int _bit = db[_byteDB, _i];


                    if ( _bit == 1 )
                    {
                        _byte += (int) Math.Pow(2, _i);
                    }
                }


                Console.WriteLine("Zustand von DB Byte " + _byteDB + ": " + _byte);


                return (byte) _byte;
            }


            public byte get_state()
            {
                int _state = 0;


                state.lifebit = !state.lifebit;


                _state = (state.connection) ? _state | stateMask.CONNECTION : _state | 0;
                _state = (state.lifebit) ? _state | stateMask.LIFEBIT : _state | 0;
                _state = (db[18, 2] == 1) ? _state | stateMask.RESET : _state | 0;


                return (byte) _state;
            }


            public void open ()
            {
                try
                {
                    serialType.rfd = libnodave.openSocket(102, ipAdress);


                    serialType.wfd = serialType.rfd;


                    if (serialType.rfd > 0)
                    {
                        iFace = new libnodave.daveInterface(serialType, "IF1", 0, libnodave.daveProtoISOTCP, libnodave.daveSpeed187k);
                        iFace.setTimeout(5000);


                        connection = new libnodave.daveConnection(iFace, 0, rack, slot);


                        if (connection.connectPLC() == 0)
                        {
                            connected = true;
                            error = false;
                        } else
                        {
                            connected = false;
                            error = true;
                        }                    
                    }


                }
                catch (Exception _e)
                {
                    Console.WriteLine(" No Connection! ");
                    connected = false;
                    error = true;
                    return;
                }
            }


            public int read ( int _startByte, int _length, int _db = 0)
            {
                _db = ( _db == 0 ) ? standardDB : _db;


                if ( _length == 0 ) return 0;


                return connection.readBytes( libnodave.daveDB, _db, _startByte, _length, null );
            }


            public void write ()
            {
                int _tmp = (state.lifebit) ? 3 : 1;


                byte[] _states = {
                    // Bereich Funktionstasten DBD 10
                    //10, 11, 12, 13
                    get_byte(10), get_byte(11), get_byte(12), get_byte(13), 
                    // Bereich Kundentasten DBD 14     
                    //14,
                    get_byte(14), get_byte(15), get_byte(16), get_byte(17),      
                    // Bereich Status DBW 18      
                    //18, 19
                    get_state(), 0       
                };


                connection.writeBytes(libnodave.daveDB, standardDB, 10, 10, _states);
            }
        }


        public MPP483IE_Layout()
        {
            InitializeComponent();
        }


        private void MPP483IE_Layout_Load(object sender, EventArgs e)
        {


            //Verbindung zur S7 herstellen.
            s7c.open();
            
        }


        private void update_Tick(object sender, EventArgs e)
        {
            if (WindowState == FormWindowState.Minimized || Form.ActiveForm == null)
            {
                s7c.close();
                return;
            }


            if (!s7c.updating && !s7c.error)
            {
                s7c.updating = true;
                onlineLED.Visible = false;
                //Console.WriteLine("Read Outputs! ");


                try
                {


                    int res = s7c.connection.readBytes(libnodave.daveOutputs, 0, 0, 16, null);


                    int AB0 = s7c.connection.getS8();
                    int AB1 = s7c.connection.getS8();
                    int AB2 = s7c.connection.getS8();
                    int AB3 = s7c.connection.getS8();
                    int AB4 = s7c.connection.getS8();
                    int AB5 = s7c.connection.getS8();
                    int AB6 = s7c.connection.getS8();
                    int AB7 = s7c.connection.getS8();


                }
                catch (Exception _e)
                {
                    Console.WriteLine("Error while reading!");
                    s7c.error = true;
                }
 
                try
                {
                    s7c.write();
                }
                catch (Exception _e)
                {
                    Console.WriteLine("Error while writing!");
                    s7c.error = true;
                }


                s7c.updating = false;
                onlineLED.Visible = true;
            }
        }


        private void MPP483IE_Layout_Deactivate(object sender, EventArgs e)
        {
            s7c.close();
        }
    }
}


Gruß
 
Das Deactivate-Event wird aufgerufen wenn du deine Form minimierst oder in ein anderes Fenster wechselst. In diesem Event baust du die Verbindung selber ab. Und dann spricht irgendwann der Timer an, und versucht über die beendete Verbindung zu lesen.
Warum er dann zu daveGetU8 springt obwohl du in dem Programm was du hier zeigst daveGetS8 verwendest weiß ich auch nicht.

Wenn du die Verbindung beenden willst wenn das Programm beendet wird, würde ich eher das Closed Event verwenden. Dann im ersten Schritt den Timer anhalten und danach die Verbindung zur SPS trennen.

Bei Programmstart musst du die andere Reihenfolge einhalten. Also erst die Verbindung zur SPS aufbauen, und dann bei Erfolg den Timer starten.
 
Hallo Thomas,

oh man, darauf wäre ich nicht gekommen. Hatte die ganze Zeit die .dll in verdacht bzw. die Schnittstelle.
Hab jetzt das FormClose Event genommen und im Timer die Abfrage ob minimiert oder im Hintergrund entfernt jetzt funktioniert es ohne Probleme.

Vielen Dank für die Unterstützung!

Gruß
Ogoku
 
Zurück
Oben