Autor Beitrag
frenchcancan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Do 31.03.11 11:05 
Hallo!
ich kämpfe immer noch mit der Übernahme von Konfigurationsdaten über einen String. ich bekomme folgenden String: ""variable1",2000;"

In C hatte ich das so gelöst: ich vergleicheden VariablenNamen in eine Tabelle wo für jeden VariablenNamen die Adresse der entsprechenden Variable im Objekt steht. Und setze den Wert über diesen Zeiger

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
typedef struct
{  string name;
  int *p_parameter;
}t_cfglist;

t_cfglist parlist[] =
{
  {"variable1",&configObjekt.variable1},
  {"variable2",&configObjekt.variable2},
  {"variable3",&configObjekt.variable3},

}

Parsen und Wert zuweisen:
ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
for (i=0; i < 3;i++)
{
  found = strstr(s,dslist[i].name);
  if (found !=NULL) // Feldname gefunden
  {
     *dslist[i].p_parameter =  *value;// setzen des Wertes
       break;
  }
}



In C# scheitere ich damit aber schon beim Initialisieren des parlist array. Der Compiler nimmt dort keine Adresse von dem Objekt, den ich zuvor erstellt habe
Ich bekomme immer die Meldung: der Zugriff WindowsFormsApplication1.allParam.geraetConfig auf ist aufgrund der SicherheitsEbene nicht möglich.Was mache ich falsch? ich mache es so:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
class allParam
    {
        public static geraetConfig poloscfg = new geraetConfig();  
         public class geraetConfig
        {
            int variable1;
            int variable2;
            int variable3;
        }
        private class t_cfglist
        {
          string name;
          int *p_parameter;
        }

        t_cfglist parlist1 = new t_cfglist {
          {"variable1",&poloscfg.variable1},
            {"variable2",&poloscfg.variable2},
            {"variable2",&poloscfg.variable3}};

    }
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 31.03.11 11:51 
Hallo,

mit "Sicherheitsebene" ist hier der sog. "access modifier" gemeint, d.h. "private", "protected", "internal" oder "public".

In C# mußt du jede Klassenvariable explizit mittels obigen "Zugriffsmodifizierern" angeben, ansonsten sind diese alle "private" und man hat keinen Zugriff darauf.

Außerdem benötigst du in C# (außer für System- bzw. Interop-Kommunikation) keine Zeiger!
Oder anders ausgedrückt: dein Vorgehen ist nicht 1:1 von C bzw. C++ aus übertragbar.

Da C# intern mit Referenzen arbeitet (und die Objekte vom GarbageCollector verwaltet werden), kannst du keine Speicheradressen direkt verwenden.

Am besten, du verwendest String.Split() zum Aufteilen deiner Config-Strings und dann in einer switch-case-Anweisung (C# kann hier auch Strings vergleichen!) setzt du die einzelnen Werte.
frenchcancan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Do 31.03.11 12:07 
OK, danke schön, Das heißt also so etwas wie
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
void set("paramNname",value)
{
switch (paramName)
{
case "variable1":
     configObjekt.variable1 = value;
     break;
case "variable2":
     configObjekt.variable2 = value;
     break;
case "variable3":
     configObjekt.variable3 = value;
     break;
     
}
}

das hätte ich so gern vermioeden, weil es eine sehr große VAriablenliste ist. Aber nach gut, das mache ich dann so.
Vielen Dank!
frenchcancan

Moderiert von user profile iconChristian S.: C#-Tags hinzugefügt
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Do 31.03.11 12:21 
Hallo,

als einzige Alternative dazu fiele mir noch Reflection ein, d.h. wenn deine Klassenvariablen genauso heißen wie die Config-Parameter (alternativ natürlich mittels eines Mappings):
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
using System.Reflection;

// ...
FieldInfo fi = typeof(t_cfglist).GetField(paramName, BindingFlags.NonPublic | BindingFlags.Instance);
if (fi != null)
   fi.SetValue(poloscfg, value); // value muß jetzt entsprechend dem Parametertyp sein (d.h. bei dir 'int' - und aus einem String mittels Int32.TryParse(str, out intVar) ermittelt)
bakachan
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 503
Erhaltene Danke: 34

W7 (x64) Ultimate
C# / VB.NET (VS2010 Ultimate)
BeitragVerfasst: Do 31.03.11 12:47 
Also falls du die geraetConfig verändern kannst würde ich eher zu einem Dictionary tendieren.
ausblenden C#-Quelltext
1:
Dictionary<stringint> _values;					

(das int kannst du natürlich auch durch andere Klassen ersetzen, je nachdem was du benötigst, notfalls object)
frenchcancan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Fr 01.04.11 08:35 
Danke für die Antworten!
Ich habe es jetzt mit System.Refelction probiert aber ich bekomme immer die Meldung "nicht gefunden"
Kannst du mir noch einen tip geben?
Und geht es auch mit verschalteten Obkekten? Z. B. wenn die Klasse ein Feldname teil1.variable1 udn teil1.variable2 hätte?

Danke schön!
Mein Klasse sieht so aus:

ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
class testconfig
    {
     
            public class geraetConfig
            {
                int variable1;
                int variable2;
                int variable3;
            }
    }

Und mein Code:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
private void feldZuweisen(testconfig poloscfg, string paramName, int value)
{
        // ...
        FieldInfo fi = typeof(testconfig).GetField(paramName, BindingFlags.NonPublic | BindingFlags.Instance);
        if (fi != null)
            fi.SetValue(poloscfg, value); 
        else
            MessageBox.Show("nicht gefunden");

}

private void Form1_Load(object sender, EventArgs e)
{
            string neuerParameter;
            string[] textAbschnitte;
            testconfig poloscfg = new testconfig();
            Match m;
            int value;


             neuerParameter = "variable1;2000";
             textAbschnitte = neuerParameter.Split(';');
             m = Regex.Match(textAbschnitte[1], @"\d+");
            if (!int.TryParse(textAbschnitte[1].Substring(m.Index, m.Length), out value))
                        value = -1;
            feldZuweisen(poloscfg, textAbschnitte[0], value);

}
frenchcancan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Fr 01.04.11 08:45 
user profile iconbakachan hat folgendes geschrieben Zum zitierten Posting springen:
Also falls du die geraetConfig verändern kannst würde ich eher zu einem Dictionary tendieren.
ausblenden C#-Quelltext
1:
Dictionary<stringint> _values;					

(das int kannst du natürlich auch durch andere Klassen ersetzen, je nachdem was du benötigst, notfalls object)


Hallo! Danke für die Antwort.

Ein Dictionary wäre natürlich schön, weil ich keine festgelegt Objektstruktur hätte, sondern sie einfach beim Einlesen bilden würde.
Aber geht es auch mit verschachtelte Objekten?
In der Realität bekomme ich nämlich einen String mit "spin.admin.variable1;value"
oder "spin.admin.variable2;value" und dann spin.service.variable3"
und würde es in Baumform darstellen.
Kann ein Dictionary so etwas leisten? oder ist es zu kompliziert?

Danke schön!
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4805
Erhaltene Danke: 1061

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 01.04.11 09:38 
Hallo frenchcancan,

in dem Reflection-Code mußt du schon die richtige Klasse (d.h. den Typ) angeben, d.h.
ausblenden C#-Quelltext
1:
typeof(testconfig.geraetConfig)					

(und auch deine Variable 'poloscfg' bei SetValue muß dann von diesem Typ sein!)

Automatisch sucht er nicht in untergeordneten Klassen.
Auch bei einem Dictionary geschieht das nicht automatisch.

Vllt. solltest du noch mal genauer beschreiben, wie deine Config-Datei aussieht und wie du dir dann die Config-Klassen in deinem Programm vorstellst?
frenchcancan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Fr 01.04.11 10:08 
Hallo,
vielen Dank, ich verstehe was falsch war, es war tatsächlich
Gerade hat eine Besprechung meine Versuche aber zurücjk geworfen, da wir das Programm doch mit Net 4.0 machen wollen, damit die REstellung dynamischer Objekte erlaubt sind.
Da muss ich mich wohl erstmal einlesen müssen...

Meine Konfigurationsdatei ist eingentlich relativ komplex, deswegen hatte ich sie nicht geschickt. sie hat 3 Ebenen: 1. Ebene Geräte: spin, dispense arm (bis 3 ), z-achse
jede Ebene ist unterteilt in 4 Bereichen: operator,admin,service, factory und in der letzten Ebenen sind die eigentlichen Parameter, die die Geräte beschreiben (maximale Speed, Länge, Anzahl Ventile, usw...)
verkürzt sieht sie so aus:(Siehe am Ende des Beitrages)
da das Gerät aus dem ich lese aber eine eigene Konfiguration hat (es fehlen ihm zum Beispiel ein dispense arm oder eine Z-Achse), weiß ich beim Einlesen noch nicht, wie das Ziel Objekt aussehen wird.

Ich werde also über die USB Schnittstelle Text bekommen wie
"spin.admin.language;0"
oder
"spin.oper.nextstepavail;1"
oder
"spin.factory.maxspeed;10000"
oder
"da[0].admin.parklspeed;12"
Ich stelle es mir so vor, dass ich beim Einlesen das verschachteltes Konfigurationsobjekt bilde und die werte zuordne und es dann als treeview anzeige. Mal gucken, ob es klappt.
Falls ihr tips habt, sehr gerne!
Vielen Dank und ein schönes erholsames Wochenende nachher

Konfigurationsobjekt, wie es sein kann:

ausblenden volle Höhe C#-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
public class PolosConfig
{
    
    spinclass spin;
    zaclass za;
    daclass[] da = new daclass[3];
}
 public class spinclass
    {
        spinoper oper;
        spinadmin admin;
        spinservice service;
        spinfactory factory;


        public class spinoper
        {
            int nextstepavail;
            int backtostartpos;
            int terminal;
        }
        public class spinadmin
        {
            int language;
            int vakuum_on;
            int emerg_decc;
            int emerg_novac;

        }
        public class spinservice
        {
            int lidvariations;
            int depouts;
        }
        public class spinfactory
        {
            int servo;
            int valvefrom;
            int valveto;
            int hallsensor;
            int maxspeed;
        }

    }
 public class daclass
    {
        daoper oper;
        daadmin admin;
        daservice service;
        dafactory factory;

        public class daoper
        {
            int oper_startpos_rad;
        }
        public class daadmin
        {
            int posspeed;
            int parkspeed;
            int parkposdiamm;
            int predipensediam;

        }
}
usw...
Kha
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic star
Beiträge: 3803
Erhaltene Danke: 176

Arch Linux
Python, C, C++ (vim)
BeitragVerfasst: Fr 01.04.11 10:44 
Bei dem Umfang würde ich auf jeden Fall auf Reflection setzen. Du musst eben diesen "Property-Pfad" (oh, ok, du hast ja gar keine Properties ;) ) parsen, dich vom Wurzelobjekt aus durchhangeln und dann das angegebene Feld setzen.

_________________
>λ=
frenchcancan Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 27



BeitragVerfasst: Fr 01.04.11 10:48 
user profile iconKha hat folgendes geschrieben Zum zitierten Posting springen:
Bei dem Umfang würde ich auf jeden Fall auf Reflection setzen. Du musst eben diesen "Property-Pfad" (oh, ok, du hast ja gar keine Properties ;) ) parsen, dich vom Wurzelobjekt aus durchhangeln und dann das angegebene Feld setzen.


OK, vielen Dank,
ich versuche es mit Refelection.