2016-02-23 2 views
1

Я создаю DLL для приложения. Приложение вызывает DLL и получает строку длиной от 8 до 50.LPTSTR содержит только одну букву

Проблема, с которой я столкнулся, заключается в том, что отображается только первая буква любого сообщения, которое получает приложение.

Ниже приведена функция GetMethodVersion.

#include "stdafx.h" 
STDAPI_(void) GetMethodVersion(LPTSTR out_strMethodVersion, int in_intSize) 
{ 
    if ((int)staticMethodVersion.length() > in_intSize) 
     return; 
    _tcscpy_s(out_strMethodVersion, 12, _T("Test")); 
    //staticMethodVersion should be insted of _T("Test") 
} 

Настройки проекта установлены в Юникод. Я верю после некоторого исследования, что есть проблема с форматом Unicode и тем, как он функционирует. Спасибо за любую помощь, которую вы можете дать.

+0

Почему существуют три строки кода: 'out_strMethodVersion',' staticMethodVersion', 'out_String'? – Dialecticus

+0

Извините, удалили кучу ненужного кода и, должно быть, пропустили переименование – PonWer

+0

Где вы видите одну букву в одной из окон отладки Visual Studio или в консоли или графическом интерфейсе вашего приложения? Может быть, строка Unicode, но Visual Studio думает, что это не так? Посмотрите на строку непосредственно в памяти и посмотрите, есть ли другие буквы, разделенные 00 байтами. – Dialecticus

ответ

2

В вашем вопросе вы указали, что параметры проекта Unicode: это верно для и DLL и вызывающий EXE? Убедитесь, что они оба совпадают.

В Unicode строит, уродливые макросы TCHAR стали:

LPTSTR  --> wchar_t* 
_tcscpy_s --> wcscpy_s 
_T("Test") --> L"Test" 

Так у вас есть:

STDAPI_(void) GetMethodVersion(wchar_t* out_strMethodVersion, 
           int in_intSize) 
{ 
    ... 
    wcscpy_s(out_strMethodVersion, 12, L"Test"); 
} 

Вы уверены, что "магическое число" 12 правильно? Является ли буфер строки назначения указанным out_strMethodVersion размером не менее 12 wchar_t s (включая завершающий NUL)?

Затем ознакомьтесь с сайтом для звонков (который вы не указали).

Как вы печатаете возвращаемую строку? Может быть, вы используете ANSI функции обугленного, поэтому возвращаемая строка неверно истолкованы как ANSI строку char*, и поэтому первый 0x00 байт Unicode UTF-16 строка ошибочно интерпретируется как NUL-терминатор на месте вызова, и строка печатается при первом символе при печати?

Text:    T  e  s  t  NUL 
UTF-16 bytes: 54 00 65 00 73 00 74 00 00 00 
    (hex)   **<--+ 
         | 
       First 00 byte misinterpreted as 
       NUL terminator in char* ANSI string, 
     so only 'T' (the first character) gets printed. 

EDIT

Тот факт, что вы разъяснены в комментариях, что:

Я переключил DLL в ANSI, то EXE-видимому, в том, что, как хорошо, хотя exe был задокументирован как Unicode.

заставляет меня думать, что EXE предполагает кодировку Unicode UTF-8.

Подобно тому, как в строках ANSI, A 0x00 байт UTF-8 является строка NUL-терминатор, так что предыдущий анализ UTF-16 0x00 байт (в wchar_t) неверно истолкован, как применяется строка NUL-терминатор.

Обратите внимание, что чистый ASCII является подходящим подмножеством UTF-8: поэтому ваш код может работать, если вы просто используете чистые символы ASCII (например, в "Test") и передаете их в EXE.

Однако, если EXE задокументирован использованием Unicode UTF-8, вы можете захотеть сделать правильную вещь и вернуть строку UTF-8 из DLL.

Строка возвращается через char* (как для строк ANSI), но важно, что вы убедитесь, что UTF-8 это кодировка используется DLL, чтобы вернуть эту строку, чтобы избежать тонких ошибок в будущем.

Хотя общая терминология, используемая в ОС Windows API, и в Visual Studio является "Unicode", это на самом деле означает UTF-16 кодировки Unicode в этих контекстах.

Однако UTF-16 не является единственной кодировкой Unicode. Например, для обмена текстом в Интернете широко используется кодировка UTF-8. В вашем случае это похоже на то, что ваш EXE ожидает строку Unicode UTF-8.

+0

Вы, почта, заставляли меня думать. До сих пор я предполагал, что вызывающий exe был unicoded, поскольку он был задокументирован как таковой. Однако переход на ANSI исправил его! – PonWer

+0

@PonWer Возможно, вызывающий использует UTF-8 вместо UTF-16? Тот факт, что переключение на ANSI устраняет проблему, означает, что вызывающий абонент определенно не использует UTF-16. –

+0

@PonWer: Что именно вы переключили на ANSI? И DLL, и вызывающий EXE? Или у вас есть Unicode (UTF-16) DLL и EXE, построенный с использованием ANSI/MBCS? Просьба уточнить. Убедитесь, что как DLL, так и вызывающий EXE обмениваются данными с использованием текстового формата _same_ или обеспечивают надлежащее преобразование на границах. Как вы можете прочитать в комментарии @ RaymondChen, существуют различные кодировки Unicode, например. UTF-8 и UTF-16. Я предположил _ «Unicode == UTF-16» _ в своем ответе (что является общим предположением в макросах препроцессора Visual Studio, '_UNICODE/UNICODE' и т. Д.). –

0

До конца #define UNICODE после #include "stdafx.h". Он должен быть определен до первого #include в stdafx.h. Но правильный способ - установить его в свойствах проекта (меню «Проект»> «Свойства»> «Свойства конфигурации»> «Основные»> «Набор символов»> «Использовать набор символов Юникода»).

+0

Хорошо, я изменил его в настройках проекта, однако проблема осталась – PonWer

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

  • Нет связанных вопросов^_^