2014-01-21 10 views
5

Ich wurde gebeten, Funktionalität zu einem bestehenden alten Projekt hinzufügen, aber ich kann es nicht zu bauen. Es behandelt Unicode-Strings, aber ich bekomme eine Menge Fehler in Bezug auf die Verwendung von TCHAR.Speziell fast jeder Fehler ist TCHAR kann nicht konvertiert oder als wchar_t verwendet werden. Von dem, was ich auf vielen verschiedenen Artikeln sah, versuchte ich mit #define_UNICODE oder #define UNICODE, aber keiner von ihnen löste das Problem.Fehler bei der Verwendung von TCHAR, kann nicht in wchar_t konvertiert werden

Hier ist ein Stück des Codes:

#include <windows.h> 
#include <wininet.h> 
#include <tchar.h> 
#include <iostream> 
#include <fstream> 
#include <strsafe.h> 
#include <string> 
#include <list> 
#include <cctype> 
#include <winnt.h> 
#include <atlconv.h> 

#pragma comment(lib,"wininet.lib") 

using namespace std; 

TCHAR *tags[] = { _T("aa"), _T("bb"), _T("cc"), 
NULL }; 

int _tmain(int argc, _TCHAR* argv[]) 
{ 


int i = 0; 


for (i = 1; i<argc; i++) { 
    if (wcscmp(argv[i], _T("-h")) == 0) { 
     ... 
    } 
    else if (wcscmp(argv[i], _T("-f")) == 0) { 
     ... 
    } 


... 
} 

In den obigen Zeilen beispielsweise bei der Verwendung von wcscmp, i

argument of type "_TCHAR *" is incompatible with parameter of type "const wchar_t *" 

über die argv [i]

erhalten und

argument of type "const char *" is incompatible with parameter of type "const wchar_t *" 

zurück ding das _T ("- h").

Alle Vorschläge würden sehr geschätzt werden.

Antwort

8

Der Code wurde in Ziel-Unicode statt MBCS geschrieben. Dies kann durch die Verwendung von wcscmp erkannt werden, die Parameter des Typs const wchar_t* akzeptiert. Auf der anderen Seite gibt es Teile des Codes, die TCHAR und zugehörige Makros verwenden. Jetzt ist TCHAR ein Makro, das entweder in char oder wchar_t aufgelöst wird, je nachdem, ob _UNICODE oder _MBCS definiert sind oder nicht. Konsultieren Sie die documentation für weitere Details. Die Verwendung von TCHAR stammt aus den Tagen, als Entwickler Code für Windows NT/2000 (unterstützt sowohl ANSI- als auch Unicode-APIs) und Windows 95/98 (mit nur ANSI-APIs) schreiben wollten. Die Verwendung von TCHAR ermöglichte eine gemeinsame Codebasis. Kompilieren Sie mit _UNICODE für NT/2000 definiert, und kompilieren Sie mit _MBCS für 95/98 definiert.

Wenn Sie in diesem Stil codieren, dann schreiben Sie _tcscmp statt wcscmp.Für einen Unicode-Build wird wcscmp aufgelöst und für einen MBCS-Build wird er in _mbscmp aufgelöst.

Heutzutage müssen Sie normalerweise keinen Code schreiben, um 95/98 zu unterstützen. Sie können diese Plattformen wahrscheinlich vernachlässigen. In diesem Fall sollten Sie Unicode als Ziel verwenden und aufhören, TCHAR und zugehörige Makros zu verwenden. Ersetzen Sie _T("..") durch L"..". Ersetzen Sie tmain durch wmain. Ersetzen Sie TCHAR durch wchar_t. Und so weiter.

Sie müssen diese Änderungen nicht vornehmen. Sie könnten einfach Unicode ausrichten und Ihr Code wird kompiliert. Das TCHAR-Idiom wurde jedoch in Ihrer Codebasis inkonsistent angewendet. Beachten Sie die Verwendung von _tmain, TCHAR, aber auch die Aufrufe an wcscmp. Daher kann der Code nicht kompiliert werden, wenn Unicode nicht darauf ausgerichtet ist. Sie verlieren also nichts, indem Sie TCHAR aufgeben. Was Sie gewinnen, ist Klarheit. Sie können aufhören, diese Makros zu verwenden und alle von ihnen bereitgestellten Verschleierungen zu vermeiden. Indirection ist ein großartiges Werkzeug, aber wenn es nicht benötigt wird, führt es einfach zu Verwirrung und Verschleierung.

+0

sehr nette antwort! Ich habe mich wirklich gefragt, ob diese art von codierung tatsächlich notwendig war. Danke david! – yiannis

1

Es sieht so aus, als würden Sie Ihre Anwendung nicht für Unicode erstellen, überprüfen Sie daher Ihre Projekteinstellungen.

Wenn Sie die Wide-String-Funktionen wie wcscmp verwenden, dann hat es keinen Sinn, den _T()-Makro zu verwenden, da Ihr Compiler nicht kompiliert wird, wenn er im Nicht-Unicode-Modus kompiliert wird. Wenn Sie möchten, dass der Code in beiden Modi kompiliert wird, wenn Sie die TCHAR aware-Funktionen in <tchar.h> wie _tcscmp verwenden müssen.

Wenn Sie immer ein String sein breit dann wollen ein L an der Stelle aus, zB L"Hello, world"

+0

Vielen Dank für Ihre Hilfe. Das Ändern der Einstellungen löst das Problem, also habe ich mich gefragt, was Sie sagten, gibt es einen Fall, dass ich im Nicht-Unicode-Modus kompilieren möchte? – yiannis

+0

@yiannis Ich habe versucht, das in meiner Antwort zu adressieren. Ich denke, Sie sollten mehr tun, als nur auf das Unicode-Targeting zu wechseln. Ich denke, du solltest das verwirrende TCHAR-Idiom loswerden, das inkonsistent verwendet wurde. –

1

Wenn Sie Visual Studio verwenden, setzen Zeichensatz-Verwenden Unicode-Zeichen unter Projekt Konfigurationsset Eigenschaften.

Ich denke, Sie könnten #define UNICODE verwenden, aber stellen Sie sicher, dass Sie es tun, bevor irgendwelche enthält.