Buffer löschen



  • Hallo zusammen,

    Ich nutze eine DLL um eine FileBox zu öffnen usw. Über die Variable Buffer soll der Pfad an das Programm übergeben werden, welches die DLL aufruft!

    Folgendes Problem tritt auf: Übergebe ich zuerst einen längeren Pfad an das Programm und beim zweiten Aufruf einen kürzeren, dann wird der restliche Teil des vorherigen Pfades nicht überschrieben sondern angehängt

    Beispielausgabe:C:/test/test.cppest/test/test1.cpp

    Ich vermute mal das der Buffer nicht vollständig gelöscht wird. Habe schon sämtliche sachen ausprobiert, allerdings ohne erfolg!
    Kann mir da einer weiter helfen!

    extern "C" __declspec(dllexport) void CdwDLLGet(long id, long* buflen, char* buffer)
    {
     //Benötigtes Makro zur anzeige des Dialogs
       AFX_MANAGE_STATE(AfxGetStaticModuleState()); 
    
     //Variable, die die FileSelektorBox öffnet
       CFileDialog dlgFile(TRUE);
    
       //FileSelektorBox wird geöffnet
         if(dlgFile.DoModal() == IDOK)
         {
    		  //Initialisierung einer leeren Variable
    			CString zero;
    		  //Initialisierung von Variablen
    		  	long maxbuf;
    	        int  len;
    			int leer;
    			char test[99];
    			char test1[99];
    
        	    //Pfadübergabe an die Variable
    			  CString pfad(dlgFile.GetPathName());
    
    			  leer = strlen( zero );
    			  itoa(leer, test1, 10);
    
    			//Ausgabe der Länge/Größe der Variable
    			  len = strlen( pfad );
    		    //len wird in ein string umgewandelt
    			  itoa(len, test, 10);
    
    			//AfxMessageBox(test);
    
    			maxbuf = *buflen; 
    		  // Bufferlänge übergeben
    			*buflen = 5 + len;
    
    			//maxbuf2 = *buflen;
    			//*buflen = 5 + leer;
    
    		  //Buffer wird auf 0 gesetzt
    			memcpy(&buffer[5], zero, leer);
    
    		  //Der Wert 00011 wird übergeben
    	        memcpy(buffer, "00011", 5);
    		  //Übergabe des Pfades ab dem 6 Zeichen
    	     	memcpy(&buffer[5] , pfad , 300 );
    
    			//AfxMessageBox(zero);
          }
    }
    

    Vor lauter ausprobieren gestern habe ich in meinem Code warscheinlich ein kleines durcheinander. Ich hoff ihr kommt trotzdem zurecht!?

    Danke schon mal!

    Gruß Elle



  • du dem zusammenbasteln von buffer solltest du noch ein '\0' anhängen. dann sollte es auch funktionieren



  • Sorry, aber ich weiss nicht was Du mit '/0' meinst bzw. weiss ich nicht wohin damit 😕



  • Füge das mal noch am ende ein:

    buffer[*bufflen+1] = '\0';
    


  • Leider hat das nicht funktioniert!!! 😞



  • Hallo,
    hab mal wieder Zeit gefunden auf dieses Thema zurück zu greifen!!!

    Hab um herauszufinden was das Programm macht unter jedem Vorgang eine Messag Box eingebaut. Vielleicht kann mir ja nach dieser Erklärung jemand helfen!!! 😕

    //Initialisierung einer leeren Variable
    			CString zero;
    		  //Initialisierung von Variablen
    		  	long maxbuf;
    	        int  len;
    			char test[99];
    
    			  AfxMessageBox(buffer);
    

    Habe an den Anfang gleich mal eine MB gesetzt um zu sehen was sich in der Variable buffer befindet. Wird die FileBox zum 1. Mal aufgerufen befindet sich in der Variable zuerst Datenschrott. Wird zum 2. Mal ein Pfad übergeben befindet sich in dieser Variable der vorherige Pfad, obwohl am Ende der buffer auf 0 gesetzt wird.

    Anschließend übergebe ich den ausgesuchten Pfad an die Variable pfad

    //Pfadübergabe an die Variable
    			  CString pfad(dlgFile.GetPathName());
    			  AfxMessageBox(pfad);
    

    In der MB wird der richtige Pfad angezeigt

    Danach lass ich mir die Länge des übergebenen Pfades anzeigen, der Stimmt auch soweit

    //Ausgabe der Länge/Größe der Variable
    			  len = strlen( pfad );
    		    //len wird in ein string umgewandelt
    			  itoa(len, test, 10);
                  AfxMessageBox(test);
    

    Für das aufzurufende Programm werden zuerst die unten angegebene Zeichen benötigt, die ich wie folgt über die Variable buffer ausgebe

    maxbuf = *buflen; 
    		    // Bufferlänge übergeben
    			  *buflen = 5 + len;
    
    			  //Der Wert 00011 wird übergeben
    	          memcpy(buffer, "00011", 5);
    			  AfxMessageBox(buffer);
    

    Ab hier fängt das Problem schon an. Die Zeichen werden zwar übergeben, allerdings wird beim ersten Durchlauf Datenschrott mitgeliefert. Beim 2. Durchlauf befindet sich dann noch der vorherige Pfad in der Variable was bedeutet das bei einer kürzeren Pfadangabe noch der Rest des alten Pfades zu sehen ist!

    Anschließend übergebe ich den Inhalt aus der Variable pfad an die Variable buffer, und wie bereits erwähnt wird dann in dieser MB dann der Rest des alten Pfades noch mit angezeigt.

    //Übergabe des Pfades ab dem 6 Zeichen
    	     	  memcpy(&buffer[5] , pfad , len);
    		      AfxMessageBox(buffer);
    

    Da danach setzte ich dann den buffer auf 0. Die MB ist auch leer, allerdings wird beim erneuten start der FileBox die obere MB wieder mit dem alten Pfad angzeigt.

    buffer = '\0';
    	          AfxMessageBox(buffer);
    

    Ich hoff es kann mir jemand helfen, denn es wäre super dringend!!! 😞

    Ich habe mir auch schon überlegt den Rest mit Leerzeichen zu füllen. Würde das gehen? Wenn ja, wie?

    Gruß Elle



  • Hi,

    ich muss zugeben, dass ich das, was ich jetzt sage, nicht getestet habe, also ohne Gewähr! 🤡
    [EDIT]
    Habs eben getestet, scheint zu funktionieren !

    Du solltest Dir mal in der MSDN ansehen, wie strings in Standard-C funktionieren, insbesondere die Terminierung von Strings ist ziemlich wichtig!
    [\EDIT]

    1. Wie gross ist die Variable definiert, auf die buffer zeigt? Hast Du genug Platz für den Pfad vorgesehen?

    2. Beim Füllen von buffer mit dem "00011" solltest Du mal folgendes machen:

    buffer[5] = '\0';
    

    Damit müsste eigentlich die Anzeige in Deiner Messagebox an dieser Stelle OK sein.

    3. Nach dem memcpy des Pfades das gleiche Spiel wie eben, nur minimal anders:

    buffer[5 + len] = '\0';
    

    Damit sollte jetzt buffer die 00011 + den Pfad enthalten.

    Warum Du zum Schluss den buffer auf '\0' setzt, weiss ich nicht, denn damit setzt Du ja den Inhalt auf leer...

    Lass mich wissen, ob es jetzt funktioniert...

    Gruss

    yeti



  • Hallo,

    danke für die Hilfe. Habe das ganze eingebaut, aber so richtig will es nicht funktionieren!!!

    Die erste Funktion funktioniert

    maxbuf = *buflen; 
           //Bufferlänge übergeben
    		 *buflen = 5 + len;
    
    	   //Buffer wird gelöscht
    		 buffer[5] = '\0';
    
    	   //Der Wert 00011 wird übergeben
    	     memcpy(buffer, "00011", 5);
    

    Die 2. funktioniert zwar auch aber er übergibt mir durch das memcpy den falschen buffer an das Programm

    maxbuf = *buflen; 
           //Bufferlänge übergeben
    		 *buflen = 5 + len;
    
    	   //Buffer wird gelöscht
    		 buffer[5] = '\0';
    
    	   //Der Wert 00011 wird übergeben
    	     memcpy(buffer, "00011", 5);
    	   //Übergabe des Pfades ab dem 6 Zeichen
    	     memcpy(&buffer[5], pfad , len);
    		 //memcpy(buffer + 5,pfad, len);
    
    	   //Buffer wird nach der Pfadlänge gelöscht
    	     buffer[5 + len] = '\0';
    

    Wenn ich unter dem 2. memcpy eine MB ausgeben, dann wird der vorherige Pfad mit dem aktuellen Pfad angezeigt. Setze ich zusätzlich unter buffer[5...] eine MB dann wird genau das angezeigt was ich benötig. Allerdings wird ja der buffer über das memcpy übergeben und somit ist das ganze ja nicht richtig!!! 😕

    Unter anderem hab ich folgendes probiert! Ich habe die übergebene Bufferlänge auskommentiert gehabt

    //Bufferlänge übergeben
    		 *buflen = 5 + len;
    

    Daraufhin hat er mir den vorherigen Pfad überschrieben, d.h. es war genau so wie ich es wollte, allerdings habe ich in dem Programm 4 Zeilen für die Ausgabe des Pfades angelegt (falls der Pfad extrem lang sein sollte)! Auf jeden Fall befindet sich in den anderen Zeilen nun Datenschrott. Setze ich die Bufferlänge wieder ein, dann ist der Datenschrott zwar weg, aber der vorherige Pfad wird nicht überschrieben!!!!

    Ich hoff es ist verständlich was ich meine!!!

    Gruß Elle



  • Hi,

    sieht so aus als müssten wir noch mal die Grundlagen festlegen.

    Weisst Du, wozu die Terminierung eines Strings gut ist (Diese '\0', die wir an ein paar Stellen eingebaut haben)?

    Zum einen: Du hast folgendes gemacht:

    //Buffer wird gelöscht
             buffer[5] = '\0';
    
           //Der Wert 00011 wird übergeben
             memcpy(buffer, "00011", 5);
    

    Dir ist schon klar, dass das "suboptimal" 😃 ist? Die Reihenfolge ist nämlich nicht richtig, es müsste so aussehen (Ich habe auch die Kommentare angepasst):

    // buffer wird mit Wert 00011 gefüllt
             memcpy(buffer, "00011", 5);
    
           //buffer wird terminiert, damit string-operationen funktionieren
             buffer[5] = '\0';
    

    So, damit steht im buffer der String "00011", das ist der erste Streich.
    Dann kannst Du den Pfadnamen anhängen (ab dem 6. zeichen, d.h. Index 5):

    //Übergabe des Pfades ab dem 6 Zeichen
             memcpy(&buffer[5], pfad , len);
             //memcpy(buffer + 5,pfad, len);
    
           //Buffer wird nach der Pfadlänge + 5 terminiert
             buffer[5 + len] = '\0';
    

    OK, damit sollte der buffer richtig gefüllt sein.

    Gruss

    yeti



  • Hallo,

    nein ich weiss nicht wirklich wofür die '\0' steht. Ich war immer der Meinung das wären Leerzeichen!!! War wohl falsch gedacht!!!! 😕

    Das mit der Rheienfolge stimmt bei mir im Code. Ich hab warscheinlich falsch kopiert. 🙄

    Das ganze funktioniert ja soweit auch, allerdings wird der Falsche Inhalt an das Programm übergeben.
    Ich habe die Kommentare noch nicht geändert!! --> Danke!!!

    //Der Wert 00011 wird übergeben
    	     memcpy(buffer, "00011", 5);
    	   //Buffer wird gelöscht
    		 buffer[5] = '\0';
    		 AfxMessageBox(buffer);
    

    Ausgabebeispiel:00011
    Das ist ja richtig so!

    //Übergabe des Pfades ab dem 6 Zeichen
    	     memcpy(&buffer[5], pfad , len);
    		 //memcpy(buffer + 5,pfad, len);
    		 AfxMessageBox(buffer);
    

    Ausgabebeispiel:00011C:\Benutzer\test\allgemein\test.cppalsch\kreis.cpp
    Das nicht fett gedruckte ist der Rest des vorherigen Pfades. Dieser Teil wird an mein Programm übergeben (memcpy).

    //Buffer wird nach der Pfadlänge gelöscht
    	     buffer[5 + len] = '\0';
    		 AfxMessageBox(buffer);
    

    Ausgabebeispiel:00011C:\Benutzer\test\allgemein\test.cpp
    Hier stimmt das ganze dann wieder!Genau diesen Eintrag sollte eigentlich an mein Programm übergeben werden!!! Aber wie bereits erwähnt wird der obere Teil übergeben!!!

    Hat das wirklich nichts mit diesem Bereich zu tun?!

    maxbuf = *buflen; 
           //Bufferlänge übergeben
    		 *buflen = 5 + len;
    

    Danke, ich hoff das klappt bald, denn ich weiss nicht was ich sonst noch ausprobieren soll!!! 😞
    Gruß Elle



  • Hi Elle,

    ich denke das kriegen wir schon noch hin - wie heisst es: "Don't Panic!" 😃

    Und nun dazu: Die Standard-C Strings sind Zeichenfolgen, die mit einem '\0' abgeschlossen werden. Alle Stringoperationen (also auch die Ausgabe in Messageboxen) verlassen sich auf diese sogenannte Terminierung. Deshalb auch die entsprechenden Befehle, mit denen wir dieses Zeichen jeweils an das Ende des Strings gesetzt haben, das hat funktioniert.

    Nun meine Fragen/Anregungen:

    - Du schreibst, an Dein programm würde ein längerer String übergeben als gewünscht. Das kann eigentlich nicht sein, wenn der Inhalt von buffer vor dem Rücksprung so ist, wie Du ihn beschreibst:

    Ausgabebeispiel:00011C:\Benutzer\test\allgemein\test.cpp

    Ich habe jetzt zwei Bitten an Dich:

    - Lass Dir doch mal am Ende der Funktion (vor der }, die das if-Kommando abschliesst) buffer und buflen anzeigen und lass mich wissen was jeweils drinsteht.
    - Poste nochmal die komplette Funktion (Ich habe inzwischen leicht den Überblick verloren).

    Gruss

    yeti

    PS: Dass der Pfad noch "ungültige" Zeichen enthält, wenn Du ihn nach diesen Kommandos ausgibst

    //Übergabe des Pfades ab dem 6 Zeichen
             memcpy(&buffer[5], pfad , len);
             //memcpy(buffer + 5,pfad, len);
             AfxMessageBox(buffer);
    

    sollte Dir eigentlich klar sein: Hier fehlt noch das Terminierungszeichen, das wird ja erst danach gesetzt...also ist an dieser Stelle die Ausgabe in einer Messagebox wenig sinnvoll.



  • Hier der Code noch mal

    extern "C" __declspec(dllexport) void CdwDLLGet(long id, long* buflen, char* buffer)
    {
     //Benötigtes Makro zur anzeige des Dialogs
       AFX_MANAGE_STATE(AfxGetStaticModuleState()); 
    
       //PurgeComm(buffer, PURGE_RXCLEAR); 
    
     //Variable, die die FileSelektorBox öffnet
       CFileDialog dlgFile(TRUE);
    
       //FileSelektorBox wird geöffnet
         if(dlgFile.DoModal() == IDOK)
         {
    	   //Initialisierung von Variablen
    	   long maxbuf;
    	   int len;
    	   char test[99];
    
    	   //Pfadübergabe an die Variable
    		 CString pfad(dlgFile.GetPathName());
    
    	   //Ausgabe der Länge/Größe der Variable
    		 len = strlen( pfad );
    	   //len wird in ein string umgewandelt
    	     //itoa(len, test, 10);
    
    		 maxbuf = *buflen; 
           //Bufferlänge übergeben
    		 *buflen = 5 + len;
    
    	   //Der Wert 00011 wird übergeben
    	     memcpy(buffer, "00011", 5);
    	   //Buffer wird gelöscht
    		 buffer[5] = '\0';
    		 AfxMessageBox(buffer);
    
           //Übergabe des Pfades ab dem 6 Zeichen
    	     memcpy(&buffer[5], pfad , len);
    		 //memcpy(buffer + 5,pfad, len);
    		 AfxMessageBox(buffer);
    
    	   //Buffer wird nach der Pfadlänge gelöscht
    	     buffer[5 + len] = '\0';
    		 AfxMessageBox(buffer);
    
    		 AfxMessageBox(buffer);
    		 ltoa(*buflen,test,10);
    		 AfxMessageBox(test);
          }
    

    Im buflen befindet sich die Ziffer 72 und im buffer der dazugehörige Pfad!
    Pfad hat ca. 77 Zeichen!

    Die MessageBox hab nur als Hilfe eingebaut gehabt!!!

    Gruß Elle



  • Hi Elle,

    der Code sieht doch ok aus - jedenfalls tut er das, was er soll: Am Ende (in den beiden letzten Messages) steht die Länge des Strings - also Pfadlänge + 5 sowie der komplette String - also "00011....".
    Ich habe das eben nochmal getestet, das einzige was vielleicht noch verwirrend sein kann, ist die Messagebox nach dem

    memcpy(&buffer[5], pfad , len);
    

    da zu diesem Zeitpunkt noch die Terminierung des Strings fehlt. Diese Messagebox würde ich mal rausnehmen.

    Wo ist jetzt noch das Problem?

    Gruss

    yeti



  • Das ist ja das was ich nicht versteh! Er macht ja im Prinzip alles richtig, das einzige was falsch ist, ist das was übergeben wird!!!! 😕

    Vielleicht noch was zu dem aufrufenden Programm. Das ganze wird aus COBOL raus aufgerufen. Da ja eine DLL nicht so ohne weiteres aus Cobol aufgerufen werden kann, benutze ich ein M4-Makro. Dieses Makro beinhaltet ebenfalls eine Variable mit dem Namen buffer. In diesen buffer wird über das memcpy der Inhalt des buffers aus der DLL übergeben!!!! Anschließend übergibt das Makro den Inhalt dieser Variablen an das jeweils zugeordnete Feld des COBOL-Programms.

    Da die Feldvariable auf 0 gesetzt wird, kann der Fehler nicht aus diesem Bereich kommen, was heißt, dass das ganze aus der DLL kommt!!! Und genau der falsche Eintrag aus der einen MB wird an das Makro übergeben!!!!!

    Danke noch mal für die Hilfe!!!

    Gruß Elle



  • Hi Elle,

    jetzt kommen wir der Sache schon näher - COBOL und C haben doch ziemlich unterschiedliche Stringbehandlungsmethoden...

    Beantworte mir doch mal bitte folgende Fragen:

    Was genau bekommst Du in Deinem COBOL-Programm nach Aufruf der DLL zurück (Bufferlänge und Inhalt des Buffers)?
    Was willst Du zurückbekommen, d.h. was soll für einen Beispielpfad drinstehen?
    Und was ist das für eine "Feldvariable", die angeblich auf "0" gesetzt wird?

    Gruss

    yeti



  • Hi yeti42,

    hier die Antworten, ich hoff ich hab alles richtig verstanden!!!

    Was genau bekommst Du in Deinem COBOL-Programm nach Aufruf der DLL zurück (Bufferlänge und Inhalt des Buffers)?
    

    Bufferlänge ist auf 300 Zeichen gesetzt
    Inhalt ist des Bufferst -> C:\String\string.exedll\allesmögliche.txt

    Was willst Du zurückbekommen, d.h. was soll für einen Beispielpfad drinstehen?
    

    C:\String\string.exe

    Und was ist das für eine "Feldvariable", die angeblich auf "0" gesetzt wird?
    

    Ich habe in meinem Bild ein Feld hinterlegt. In dieses Feld soll der Pfad ausgegeben werden. Die Variable ist nicht auf 0 sonder auf Space gesetzt, sorry hab mich falsch ausgedrückt

    Was mir auch noch aufgefallen ist. Manchmal macht er es richtig, meistens nach dem 3. Aufruf.
    Erklärung: Wenn in der MB in der DLL der richtige Code drin steht dann wird ab und zu trotzdem falsch übergeben! Ruf ich dann wieder die File Box auf, dann wird in der DLL und in Cobol das falsche angezeigt!

    Ich krieg noch die kriese, da ich mitlerweile nicht mehr weiss ob es an der DLL oder an dem COBOL programm liegt!!! 😡

    Gruß Elle



  • Hi Elle,

    jetzt muss ich nochmal nachfragen - da hab ich vorhin die Frage nicht ganz richtig gestellt:

    - Dein buffer ist mit 300 Zeichen maximaler Länge definiert, oder? Wenn der Pfad, der da drin steht, kürzer ist, was soll dann mit dem Rest des buffer geschehen? Soll der auf Leerzeichen, Hex-0 ('\0') oder irgendwas anderes gesetzt werden?

    - Dass Du nach dem Aufruf der DLL eine Bufferlänge von 300 bekommst, ist mir unheimlich. Da scheint was entweder im Makro oder in Deinem COBOL-Prog. faul zu sein. Was zeigt die Messagebox in der DLL am Ende an? Da sollte eigentlich der korrekte Wert drin sein!

    Mach doch mal die ganzen Messageboxen raus und lass nur noch die letzte in dieser Form drin:

    CString stest;
             stest.Format("String: %s , Länge = %ld", buffer, buflen);
             AfxMessageBox(stest);
    

    Da sollte jetzt Dein Pfad (mit 00011 vorangestellt) und die Länge des Pfades + 5 (wegen der 00011) angezeigt werden.

    Gruss

    yeti



  • Hallo yeti42,

    🙂 🙂 🙂 ich habs endlich geschaft!!!! 🙂 😃
    Vielleicht etwas umständlich aber wirksam!!!

    So funktionierts

    if(dlgFile.DoModal() == IDOK)
         {
    	   //Initialisierung von Variablen
    	   long maxbuf;
    	   int len;
    	   int i;
    	   char test1[301];
    
    	   //Pfadübergabe an die Variable
    		 CString pfad(dlgFile.GetPathName());
    
    		//Bufferlänge übergeben
        	 *buflen = 300;
    
    		//Ausgabe der Länge/Größe der Variable
    		 len = strlen( pfad );
    	   //len wird in ein string umgewandelt
    	     //itoa(len, test, 10);
    
    	      //Variable wird auf leer gesetzt	 
    		    for(i=0;i<300;i++)
    		    {
    			   test1[i]=' ';
                }
    
    	     //Terminierung auf 0
    		    test1[300] = '\0';
    
    		  //maxbuf = *buflen;
    		//Bufferlänge übergeben
        	 //*buflen = 300;
    
    	   //übergabe des Pfades an die Variable	 
    		 strncpy(test1,pfad,len);
    
    	   //Der Wert 00011 wird übergeben
    	     memcpy(buffer, "00011", 5);
    
           //Übergabe des Pfades ab dem 6 Zeichen
    	     memcpy(&buffer[5], test1 , 300);
    
    	   //Buffer wird nach der Pfadlänge gelöscht
    	     buffer[5 + len] = '\0';
          }
    

    😃 😃 😃
    Muss nur noch die Kommentare anpassen!!!

    Viiiieeeeeelen Dank für die Hilfe. 🙂

    Gruß Elle



  • Hi,

    *beckerfaustmach* 😃 😃

    Gruss + Schönes WE

    yeti


Anmelden zum Antworten