2015-03-13 2 views
3

я включать следующие файлы в моей .cpp программе:C++ типы строк путаница

#include <windows.h> 
#include <tchar.h> 
#include <stdio.h> 

Тем не менее, когда я пишу

LPCTSTR pMsg; 
DWORD msgLen; 
... 
msgLen = _tcslen(pMsg); 

Компилятор запрашивает следующую ошибку:

C2664: 'size_t strlen(const char *)' : cannot convert argument 1 from 'LPCTSTR' to 'const char *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

Конечно, я могу легко исправить проблему путем литья до LPCSTR или используя wcslen. Но это неправильно, не должен ли компилятор решать все эти вещи сам, в зависимости от макроса UNICODE? Это определенно определено, потому что, когда я пишу #define UNICODE в начале файла, компилятор запрашивает предупреждение, говоря, что он уже определен. В чем же проблема? Почему он выбирает strlen вместо wcslen?

Вот фактический код:

BOOL PrintString(HANDLE hOut, ...) 
{ 
    DWORD msgLen, count; 
    LPCTSTR pMsg; 
    va_list pMsgList; 
    va_start(pMsgList, hOut); 
    while((pMsg = va_arg(pMsgList, LPCTSTR)) != NULL) 
    { 
     msgLen = _tcslen(pMsg); 
     if(!WriteConsole(hOut, pMsg, msgLen, &count, NULL) && !WriteFile(hOut, pMsg, msgLen*sizeof(TCHAR), &count, NULL)) 
     { 
      va_end(pMsgList); 
      return FALSE; 
     } 
    } 
    va_end(pMsgList); 
    return TRUE; 
} 

Я пробовал оба #define _UNICODE и #define _UNICODE но ни не помогло. Кроме того, #define _UNICODE предлагает предупреждение, что оно уже определено.

+0

В соответствии с [docs] (https://msdn.microsoft.com/en-us/library/c426s321.aspx) управляющий макрос является '_UNICODE', а не' UNICODE'. Правильно ли вы это определили? – Angew

+0

Да, я попытался определить 'UNICODE' и/или' _UNICODE' в начале файла .cpp, но это не помогло – nicks

+0

Вы когда-нибудь планировали использовать MBCS или SBCS? Если нет, вы можете просто избавиться от всего бизнеса tchar и явно использовать wchar_t. – Angew

ответ

4

Согласно MSDN, то, что _tcslen расширяется до контролируется макросом _UNICODE. LPCTSTR, с другой стороны, контролируется UNICODE. Убедитесь, что эти два макроса определены последовательно, и перед тем, как включить любой заголовок, который может их использовать.

+0

см. Править при определении юникода – nicks

+0

@NikaGamkrelidze. У вас также есть юникод в настройках проекта VS (в свойствах проекта)? – Angew

+0

'перед любым заголовком' << это действительно трюк. Я определял _UNICODE сразу после включения. но почему это необходимо? не должны ли эти заголовки сами определять это? – nicks

2

_tcslen распространяется на strlen. LPCTSTR распространяется на const wchar_t*. Это означает, что у вас есть _UNICODE и UNICODE определяется непоследовательно. Первый используется заголовочным файлом TCHAR, последний - заголовочным файлом Windows. Учитывая ваш обновленный вопрос, я бы сказал, что вы определили UNICODE и _UNICODE не определен.

Помимо этого, вы должны сделать свою жизнь намного проще, не используя TCHAR. Это было полезно, когда вам нужно было скомпилировать один исходный код для Win9x и WinNT. В настоящее время вы, по-видимому, не нацелены на Win9x. Поэтому мой совет - просто удалить все использование TCHAR и сделать код намного проще.

+0

см. Править для фактического кода – nicks

Смежные вопросы