AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Programmieren allgemein [C] Zeichenfolge aus Funktion zurückgeben
Thema durchsuchen
Ansicht
Themen-Optionen

[C] Zeichenfolge aus Funktion zurückgeben

Ein Thema von Luckie · begonnen am 13. Sep 2006 · letzter Beitrag vom 7. Okt 2006
Antwort Antwort
Seite 1 von 2  1 2      
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

[C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 09:57
Folgender Code:
Code:
#include <stdio.h>
#include <windows.h>


TCHAR* SysErrorMessage(int ErrorCode) {
   TCHAR szBuf[80];
    LPVOID lpMsgBuf;
    DWORD dw = GetLastError();

    FormatMessage(
        FORMAT_MESSAGE_ALLOCATE_BUFFER | 
        FORMAT_MESSAGE_FROM_SYSTEM,
        NULL,
        dw,
        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
        (LPTSTR) &lpMsgBuf,
        0, NULL );

   wsprintf(szBuf, (LPTSTR)lpMsgBuf);
   LocalFree(lpMsgBuf);
   return szBuf;    
}

int main(int argc, char* argv[])
{
   printf(SysErrorMessage(5));
   return 0;
}
Leider gelingt es mir nicht eine ganz normale Zeichenfolge beliebiger Länmge aus der Funktion zurückzugeben, so dass ich sie mit printf ausgeben kann.

Zusatzaufgabe: Wie mache ich das ganze Unicode sicher?
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Vjay

Registriert seit: 2. Dez 2003
Ort: Berlin/Eschede
481 Beiträge
 
Delphi 7 Professional
 
#2

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:02
Benutzt du dort den GNU-C Compiler?

Mh, ohne jetzt eine genaue Ahnung zu haben, würde ich versuchen einen pChar zurückzugeben.

Grad mal in die Hilfe zu FormatMessage geguckt:

Zitat:
pBuffer

Points to a buffer for the formatted (and null-terminated) message. If dwFlags includes FORMAT_MESSAGE_ALLOCATE_BUFFER, the function allocates a buffer using the LocalAlloc function, and places the address of the buffer at the address specified in lpBuffer.
Denke ich weiss worauf du hinaus willst, aber Standard-C hat nicht die Super-Delphi-Stringbehandlung.
Wer später bremst ist eher tot.
  Mit Zitat antworten Zitat
Benutzerbild von ste_ett
ste_ett

Registriert seit: 10. Sep 2004
Ort: Dülmen
464 Beiträge
 
Delphi 7 Professional
 
#3

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:04
Code:
#include <stdio.h>
#include <windows.h>


TCHAR* SysErrorMessage(int ErrorCode) {
   TCHAR szBuf[80];
   LPVOID lpMsgBuf;
//   DWORD dw = GetLastError();
   DWORD dw = ErrorCode;

   FormatMessage(
      FORMAT_MESSAGE_ALLOCATE_BUFFER |
      FORMAT_MESSAGE_FROM_SYSTEM,
      NULL,
      dw,
      MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
      (LPTSTR)&lpMsgBuf,
      0, NULL );

   wsprintf(szBuf, (LPTSTR)lpMsgBuf);
   LocalFree(lpMsgBuf);
   return szBuf;    
}

int main(int argc, char* argv[])
{
   printf("%s", SysErrorMessage(5));
   return 0;
}
- übergebenen Wert aus "ErrorCode" wird jetzt zur Umwandlung genommen
- Ausgabe geändert in "printf("%s", SysErrorMessage(5));"

Ich würde einen Char-Array als Parameter übergeben, in den du schreibst, oder du holst Speicher innerhalb der Funktion und gibst ihn nach dem Aufrufen wieder frei.
Stefan
"Geht nicht!" ist keine Fehlerbeschreibung und "Hab ich schon versucht!" keine Antwort!

Hey, it compiles! Ship it!
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#4

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:20
Zitat von ste_ett:
Ich würde einen Char-Array als Parameter übergeben, in den du schreibst, oder du holst Speicher innerhalb der Funktion und gibst ihn nach dem Aufrufen wieder frei.
So komplizierte Aufrufe wollte ich eigentlich vermeiden.

Deine Version kompiliert jetzt zwar, aber es wird nur Datenmüll ausgegeben. Später will ich die Funktion SysErrorMessage auch bei einer Messagebox oder so benutzen, da geht das ja dann nicht mehr mit printf("%s", ...);.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#5

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:20
Ganz grober Schnitzer: szBuf liegt auf dem Stack, ist also nach dem Aufruf der Funktion eigentlich nicht mehr gültig. Wenn der Inhalt noch drin steht, dann hast du Glück. Ein erster Bugfix wäre, static TCHAR szBuf[80]; zu benutzen.

Allerdings ist es in C üblich, den Ergebnisparameter zusammen mit der maximalen Länge zu übergeben, wie ste_ett schon schrieb.
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#6

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:24
Also so was:
Code:
void SysErrorMessage(int ErrorCode, char* Buffer, int lenBuffer)
Nur bin ich in C noch nicht so tritt fest, wie müsste denn dann die Implementation und der Aufruf aussehen? Und ambesten noch Unicode fähig. Wir wollen ja gleich up to date sein.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von ste_ett
ste_ett

Registriert seit: 10. Sep 2004
Ort: Dülmen
464 Beiträge
 
Delphi 7 Professional
 
#7

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:30
Code:
#include <stdio.h>
#include <windows.h>

DWORD SysErrorMessage(const int ErrorCode, wchar_t* szBuf, const DWORD ArrayLength)
{
   DWORD result = 0;
   LPVOID lpMsgBuf = NULL;
   DWORD dw = ErrorCode;

   result = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM, NULL, dw,
                     MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPWSTR)&lpMsgBuf, 0, NULL);

   if (result <= ArrayLength)
   {
      wsprintf(szBuf, (LPWSTR)lpMsgBuf);
   }
   else
   {
      result = (DWORD)-1; // ErrCode
   }

   LocalFree(lpMsgBuf);

   return result;
}

int main(int argc, char* argv[])
{
   TCHAR szBuf[80];
   ZeroMemory(szBuf, sizeof(szBuf));

   if (SysErrorMessage(5, szBuf, sizeof(szBuf) / 2))
   {
      wprintf(L"%s", szBuf);
   }

   return 0;
}
z.B. so
Stefan
"Geht nicht!" ist keine Fehlerbeschreibung und "Hab ich schon versucht!" keine Antwort!

Hey, it compiles! Ship it!
  Mit Zitat antworten Zitat
Benutzerbild von Flocke
Flocke

Registriert seit: 9. Jun 2005
Ort: Unna
1.172 Beiträge
 
Delphi 10.2 Tokyo Professional
 
#8

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:31
Etwa so:
Code:
TCHAR *
SysErrorMessage (DWORD dwErrorCode, TCHAR *pszBuf, int nLenBuf)
{
  FormatMessage(
    FORMAT_MESSAGE_FROM_SYSTEM | (pszBuf ? FORMAT_MESSAGE_ALLOCATE_BUFFER : 0),
    NULL,
    dwErrorCode ? dwErrorCode : GetLastError(),
    MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),
    pszBuf ? pszBuf : (LPTSTR)&pszBuf,
    pszBuf ? nLenBuf : 0,
    NULL);
  return pszBuf;
}
// Nachtrag: noch erweitert
Volker
Besucht meine Garage
Aktuell: RtfLabel 1.3d, PrintToFile 1.4
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#9

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 10:45
Ah, ja die Version von ste_ett funktioniert und ich habe sie verstanden. Aber wäre es nicht sinnvoll die benötigte Länge des Buffers zurückzugeben, so dass man im Bedarfsfall entsprechend mehr Speicher reservieren kann? aslo:
Code:
len = SysErrorMessage(5, NULL, 0);
GetMem(szBuff, len)
SysErrorMessage(5,szBuf, len);
FreeMem(szBuf);
Das ist jetzt Delphi Pseudocode.

Und wie kann ich den Code in eine eigene Quellcodedatei auslagern? Ich habe ihn in eine eigene Datei kopiert MpuTools.cpp und eine entsprechende headerdatei angelegt: MpuTools.h, die ich dann mit include eingebunden habe:

Code:
#include <stdio.h>
#include <windows.h>
#include "MpuTools.h"

int main(int argc, char* argv[])
{
   TCHAR szBuf[80];
   ZeroMemory(szBuf, sizeof(szBuf));

   if (SysErrorMessage(5, szBuf, sizeof(szBuf)) >0)
   {
      wprintf(L"%s", szBuf);
     MessageBoxW(0, szBuf, L"Test", 0);
   }

   return 0;
}
Das mag der Compiler jedoch nicht:
Zitat:
Fehler 1 error C2144: Syntaxfehler: 'int' sollte auf ';' folgen c:\dokumente und einstellungen\mp\eigene dateien\visual studio 2005\projects\mputools\mputools_test\mputools_test .cpp 5
OK, in der Header-Datei hat ein Semikolon gefehlt. Jetzt bekomme ich aber die fehlermeldung:
Zitat:
Fehler 1 error LNK2019: Verweis auf nicht aufgelöstes externes Symbol ""unsigned long __cdecl SysErrorMessage(int,wchar_t *,unsigned long)" (?SysErrorMessage@@YAKHPA_WK@Z)" in Funktion "_main". MpuTools_Test.obj
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#10

Re: [C] Zeichenfolge aus Funktion zurückgeben

  Alt 13. Sep 2006, 13:10
OK, das Problem ist gelöst: Ich musste noch die dateien zum Projekt hinzufügen. Ich dachte das passiert irgendwie automatisch, wenn ich die entsprechende Header-Datei einbinde. Damit wäre alles geklärt. Besten Dank für eure Hilfe.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat
Antwort Antwort
Seite 1 von 2  1 2      


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:29 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz