Referenz Aufruf



  • hallo,
    hab folgendes (Anfänger) Problem, und hoffe, dass mir jemand auf die Sprünge helfen kann.
    Ich möchte ComboBox mit den Werten zur Laufzeit füllen.
    Die Werte kommen von einer externen dll von Siemens.
    die orig. Deklaration lautet

    int32 s7_get_device (int index, int *ptr, *dev_name)
    

    den Aufruf habe ich mir in eine Klassenfunktion gepackt, so dass ich die Fehler abfangen kann.
    Nun will ich jetzt aus der OnInitDialog meines Programmes die memberF. aufrufen und die char dev_name bekommen, klappts leider nicht.

    der Aufruf in OnInitDialog:

    static 
    char dev_name;
    int i = 0; // Schleifenvariable
    int32 ret = 0; // Fehlercode der Simatic Funktion
    while (ret == 0)
    	 {
    	 CTest_Verb.mF_my_get_device(i,&dev_name); 
    	 i++; }
    

    und die Funktion selbst:

    int32 CVerb_S7::mF_my_get_device(ord16 index, char *dev_name)
    {
      int32 ret;
      ret=s7_get_device(index,&m_number_ptr,dev_name);
    return ret;
    }
    

    in der Funktion selbst habe ich die richtige Ergebnisse, aber nach dem Rückkehr in OnInit.. geht die dev_name verloren.
    Was mache ich falsch?



  • Roman007 schrieb:

    Was mache ich falsch?

    Du hast dev_name zu klein gemacht. Ein char kann nur ein Zeichen aufnehmen. Die Dokumentation von s7_get_device beschreibt doch bestimmt, wie groß der Puffer sein muss, auf den dev_name zeigen soll, und ich wette, er muss größer als ein Zeichen sein.



  • Und außerdem wäre es bestimmt eine gute Idee, den Rückgabewert von mF_my_get_device() zu speichern und auszuwerten. (momentan hast du in der OnInitDialog eine nette kleine Endlosschleife)



  • Danke für die Antworten.

    Cstoll schrieb:

    momentan hast du in der OnInitDialog eine nette kleine Endlosschleife)

    die dll gibt den Code 0 zurück, wenn die F. ohne Fehler beendet wird.
    Es sind endlich viele Einträge vorhanden, also keine Gefahr der Endlosschleife.

    MFK schrieb:

    Du hast dev_name zu klein gemacht. Ein char kann nur ein Zeichen aufnehmen. Die Dokumentation von s7_get_device beschreibt doch bestimmt, wie groß der Puffer sein muss, auf den dev_name zeigen soll, und ich wette, er muss größer als ein Zeichen sein.

    Es ist egal, wie groß die char Variable setzte. Sie kommt von der dll als Zeiger auf dev_name zurück.
    Wie gesagt in der F. selbst zeigt mir Debuger richtige Werte an, wieso gibt die Funktion den Wert nicht ans Aufrufer zurück. Ich hab es doch als Referenz übergeben, dann sollte doch die Funktion die Original Var. in OnInitDialog ändern. Tuts aber nicht 😕

    Ich dachte, hätte vielleicht die Übergaben nicht verstanden. Sind sie zumindest OK?



  • while (ret == 0) 
    { 
         CTest_Verb.mF_my_get_device(i,&dev_name); 
         i++;
    }
    

    Schön, wenn mf_my_get_device() einen Rückgabewert liefert. Aber mit dieser Schleife ignorierst du diesen Rückgabewert schlichtweg (und "ret" bleibt auf dem Ursprungswert stehen). Du benötigst hier ein "**ret=**CTest_Verb. ...", um das Ende auch feststellen zu können.

    Es ist egal, wie groß die char Variable setzte. Sie kommt von der dll als Zeiger auf dev_name zurück.

    Die Funktion bekommt eine Kopie des Parameters übergeben, d.h. sie kann das ändern, worauf er zeigt (in deinem Fall den Inhalt des Zeichenpuffers), aber nicht den Wert selber (die Adresse des Puffers).



  • du hast selbstverständlich Recht, hab mich wohl vertippt.
    Es sollte ret = CTest_Verb.. heißen.

    Cstoll schrieb:

    Die Funktion bekommt eine Kopie des Parameters übergeben, d.h. sie kann das ändern, worauf er zeigt (in deinem Fall den Inhalt des Zeichenpuffers), aber nicht den Wert selber (die Adresse des Puffers).

    Wie müsste ich dann den Aufruf gestallten, damit es funktioniert?

    Ich habe noch überlegt, die ganze Schleife mit in die Memberfunktion zu packen.
    nur dann hätte an die Funktion nur die Control Variable des ComboBoxes übergeben?
    z.B. so

    CComboBox m_Zugang;
    my_get_device ( m_Zugang);
    

    Geht das überhaupt?



  • Roman007 schrieb:

    Es ist egal, wie groß die char Variable setzte. Sie kommt von der dll als Zeiger auf dev_name zurück.

    Zweimal falsch.

    Wie gesagt in der F. selbst zeigt mir Debuger richtige Werte an, wieso gibt die Funktion den Wert nicht ans Aufrufer zurück.

    In der Funktion hast du einen Pufferüberlauf, der offenbar nicht sofort zu einem Absturz führt. Wenn danach anderen Variablen auf dem Stack Werte zugewiesen werden, wird der Speicher wieder überschrieben.

    Roman007 schrieb:

    Wie müsste ich dann den Aufruf gestallten, damit es funktioniert?

    🙄
    Du musst dev_name größer machen, ein einzelner char reicht nicht.

    Geht das überhaupt?

    Sicher.



  • ... doppelt



  • MFK schrieb:

    Du musst dev_name größer machen, ein einzelner char reicht nicht.

    habe ich so geändert

    char dev_name [S7_MAX_NAMLEN+1]=" "; // =40 Zeichen
    

    gleiches Erbebnis 😞

    Ich habe mir die schleife in Klasse gepackt. wollte die Funktion dann so
    aufrufen:

    CComboBox m_Zug;
    CTest_Verb.mF_my_get_device( m_Zug);
    

    entsprechent die Schnittstelle in der Klasse.
    Da beschwert sich der Kompiler mit

    Konvertierung des Parameters 1 von 'class CComboBox' in 'class CComboBox' nicht moeglich

    Hmm? 😕



  • Roman007 schrieb:

    gleiches Erbebnis 😞

    Was machst du denn nach dem Aufruf mit dev_name?



  • alle abgefragte dev_name werden in die ComboBox eingetragen.
    wenn ich die Schleife mit den dll Aufrufen nicht in die Klasse packe, sondern direkt von OnInitDialog aufrufe, klappt es. Sieht aber Sch.. aus. 😞
    Hier das betroffene Codestück

    // s7_get_device wird wiedeholt aufgerufen und CComboBox "Zuganspunkte" gefüllt
    
    	int i = 0;     // Schleifenvariable
    	int32 ret = 0; // Fehlercode der Simatic Funktion
            char dev_name [S7_MAX_NAMLEN+1]=" ";
    	ord16 number_ptr;
    
            char *adr;
    	adr = dev_name;
          while (ret == 0)
    	 {
                ret = s7_get_device ( i , &number_ptr, adr);	     
                i++;
    	    CString str = adr;
    	    m_Zug.AddString(str); // m_Zug ist die ComboBox
    	 }
    
       m_Zug.SetCurSel(1);       // den ersten Eintrag selektieren
    

    Deswegen hätte ich das Ganze in der Klasse gehabt.

    in MFC bin ich Anfänger, das muss doch gegen, dass ich die die Variable des ComboBoxes an die Klasse übergeben kann, dann könnte ich die Funk. so lassen wie oben und schön die Box mit Daten füllen. Aber wie? 😕


Anmelden zum Antworten