der henry: c# speicher/refernz öffentlich machen

Hallo,

ich hätte da mal wieder was ;-)

Ich rufe in meiner Funktion (FK1) eine Funktion (FK2-PLCcom.TCP_ISO....) auf, die mir eine Schnittstelle öffnet. Beim öffnen der Schnittstelle wir der speicher "plcdevice" erzeugt/reserviert.

PLCDevice plcdevice = new PLCcom.TCP_ISO_Device(ip, xxx...);

Um diese Variable "plcdevice" auch in anderen Funktionen (lesen/schreiben von Schnittstelle) zu nutzen, möchte ich das "plcdevice" öffentlich wird, jedoch nur im gleichen "namespace".

Wenn es möglich wäre, würde ich das nicht über den Rückgabewert machen wollen.

Wie sollte ich hier vorgehen ... ?

Danke
  piet
  1. Ich rufe in meiner Funktion (FK1) eine Funktion (FK2-PLCcom.TCP_ISO....) auf, die mir eine Schnittstelle öffnet.

    PLCDevice plcdevice = new PLCcom.TCP_ISO_Device(ip, xxx...);
    

    Um diese Variable "plcdevice" auch in anderen Funktionen (lesen/schreiben von Schnittstelle) zu nutzen, möchte ich das "plcdevice" öffentlich wird, jedoch nur im gleichen "namespace".

    Was meinst du mit "Namespace" und, vor allem, wem soll er "gleichen"?

    Du kannst die Variable plcdevice statt innerhalb der Funktion FK1 in jenem Gültigkeitsbereich deklarieren, den FK1 und die anderen Funktionen nutzen.

    Statt

    Funktion FK1 ()
      Var plcdevice   # Deklaration
      plcdevice = new PLCcom.TCP_ISO_Device()
    
    Funktion FK2 ()
      lese(plcdevice) # Fehler, Bezeichner plcdevice ist hier unbekannt
    

    benutze

    Var plcdevice
    Funktion FK1 ()
      plcdevice = new PLCcom.TCP_ISO_Device()
    
    Funktion FK2 ()
      lese(plcdevice) # schließt übergeordneten Gültigkeitsbereich ein
    

    Das gehört aber zum kleinen Programmier-Einmaleins und sollte dir bekannt sein, weshalb ich nicht nachvollziehen kann, wo dein Problem liegt bzw. was dir unter "gleicher Namespace" vorschwebt.

  2. Hallo Henry oder Piet,

    In .net können Namespaces keine Variablen enthalten.

    Mit scheint, als sollten diese Funktionen, die sich das plcdevice teilen, Methoden einer Klasse sein. Ob du das Device dann im Konstruktor öffnest oder beim ersten Zugriff (lazy), kannst du dir überlegen. Die Variable plcdevice ist dann ein ganz normales Field dieser Klasse.

    Diese Klasse sollte das IDisposable-Muster inklusive Finalizer implementieren, damit du in der Dispose-Methode das Device sicher freigeben kannst.

    Im Detail ist das einiges an Theorie, aber ich breite mich darüber erst aus, wenn du sagst, dass du dabei mitspielst.

    Rolf

    --
    sumpsi - posui - obstruxi
    1. Hallo,

      ich komme da als c# greenhorn nicht weiter. Anbei mehr Code, der aber auf das wesentliche beschränkt ist (keine Fehler und Rückgabeauswertung) vielleicht ist es dann besser ersichtlich. Wie gesagt ich bin unter c# Anfänger und habe vllt. zu viel Beispiele gelesen ;-) .... namespace ist das nötig ???

      @Mehl: Variablen in Klammern ... wusste ich nicht.

      namespace CommPLC
      {
      	using PLCcom;
      	using PLCcom.Core;
      //###############################################################################
        public class CommPLCProgramm
        {
         public static PLCcomDevice plcdevice;
      
      //###############################################################################
          public static bool openTCP_ISO_Device(string ip)
          {
      			PLCcomDevice plcdevice = new TCP_ISO_Device(ip, 0, 2, PLCcom.ePLCType.S7_300_400_compatibel);
      			ConnectResult res = plcdevice.Connect();
      			return true;
          }
      
      //###############################################################################
          public static bool read_no_symbol()
          {
      			ReadDataRequest requestItem1 = new ReadDataRequest(eRegion.DataBlock, 10, 0, eDataType.BYTE, 10);
                  ReadDataResult res = (plcdevice).ReadData(requestItem1);
      			return true;
          }
      //###############################################################################		
        }
      }
      

      Beim Aufruf der Funktion "ReadDataResult res = (plcdevice).ReadData(requestItem1);" habe ich zur Laufzeit den "Referenzfehler"

      Sonst ist alles richtig, denn wenn ich alles in einer Funktion aufrufe, funktioniert es.

      Wie schon gesagt, bei einigem fehlt mir das Verständnis, das gab es bei reinem "C" nicht.

      Vielen Dank

      1. Hallo,

        Beitrag kann gelöscht werden, hat sich "Schreibfehler" selbst gelöst.

        Danke

      2. Hallo der henry,

        Ich sitze in Nürnberg in einem Hotelzimmer, nur mit Handy, da ist das Antworten nicht ganz leicht.

        Namespaces: ja, sind in .net nötig. Code und Daten existieren nur in Klassen, und jede Klasse existiert in einem Namespace.

        Variablen in Klammern: das hat du mistverstanden. Die Zeile

        lese(plcdevice)
        

        ruft eine Funktion lese auf und übergibt plcdevice als Argument. Also genau wie in C. Mehl hat diese Funktion nur nicht hingeschrieben, und er hat auch keine C# Syntax benutzt.

        Du hingegen hast ein PLCcomDevice-Objekt in der Variablen plcdevice und möchtest darauf eine Methode aufrufen. Dafür ist

        plcdevice.ReadData(requestItem1);
        

        völlig ok.

        Du hast einen Namespace CommPLC und eine Klasse CommPLCProgramm. In dieser Klasse hast du alles static gemacht. Das KANN man tun, aber du solltest versuchen, Programmschichten zu bilden und Verantwortungen zu bündeln.

        Das macht man in C eigentlich auch so, nur hat man da das Konstrukt der Klasse nicht und scheut auch jeden malloc(), weil das Speichermanagement in C viel rudimentärer ist als in .net.

        Ich kann dir hier am Handy keine Codebeispiele machen, tut mir leid. Als C# Bastler seit 2001 würde ich jedenfalls anstreben, eine Klasse zu erstellen, die für die Kommunikationsaufgaben des TCP_ISO_Device jeweils eine Methode anbietet, und zwar nicht static. Das Hauptprogramm erzeugt ein Objekt dieser Klasse. Eine open-Methode erzeugt das PLCcom Objekt und speichert es als Instanzvariable ("Field" in .net Sprech). Eine close-Methode räumt dieses Objekt wieder ab. Baue dem Hauptprogramm so, dass die close-Methode vor dem Ende garantiert aufgerufen wird.

        Ich frage mich auch, was du da tust. Reden wir hier über PLCcom von Indi-An, womit sich Siemens S7 SPS steuern lassen? Das ist teures Zeug, was für eine Art Programm willst du damit erstellen? U

        Rolf

        --
        sumpsi - posui - obstruxi