Почему MFC C ++ CString (const char *) полностью меняет значение const char *? - PullRequest
2 голосов
/ 20 марта 2012

Надеюсь, название было достаточно хорошим, чтобы объяснить, с чем у меня проблемы.Я думаю, что когда я решу эту проблему, мой проект будет в значительной степени завершен.Просто обратите внимание, что оба проекта скомпилированы в Unicode.

Я работаю с CLI/C++ DLL, которая принимает LPCTSTR и возвращает const char*.Если я сохраню значение возврата в const char* в моем проекте во время пошагового выполнения, я увижу, что возвращаемое значение - это то, что я ожидаю получить.

Теперь, если я сделаю следующее:

LPCTSTR strValue = L"test";
const char* Return = MethodCall(strValue);
LPCTSTR Final = CString(Return);

Return будет равен "Xmkk = Asmks" (что и должно быть).Этот метод шифрует строку.Проблема в том, что когда я делаю CString, финал будет равен "ﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮ 㹙 癞 鞮 ᠀ 諸 ²⤐²".Как мне превратить onst char* в LPCTSTR без изменения его данных "

Спасибо.

Ответы [ 3 ]

4 голосов
/ 20 марта 2012

После разрушения CString (Return) (это происходит «прямо на следующей строке после его построения») «Final» указатель указывает на освобожденный кусок памяти (который был внутренним буфером CString (Return)).На данный момент содержимое памяти, на которое он указывает, не определено, а разыменование - неопределенное поведение.Чтобы использовать указатель на внутренний буфер safelly, вы должны убедиться, что CString, которой принадлежит буфер, жив, пока есть указатель.


LPCTSTR strValue = L"test";
const char* Return = MethodCall(strValue);
LPCTSTR PointerToBuffer= 0;
{
  CString ReturnStringObj(Return);
  PointerToBuffer = ReturnStringObj;  
  // Can safelly use your pointer here  
}
// Here ReturnStringObj is killed and pointer dereferencing is invalid here




1 голос
/ 20 марта 2012

Как упоминает vnm, вы создаете временный объект CString, вызывая его конструктор в строке 3, и затем этот объект немедленно уничтожается.Это освобождает часть памяти, которую он использовал для вашего буфера, что означает, что любые попытки доступа к данным, хранящимся в этой памяти, будут неопределенным поведением.Вот почему ваша строка выглядит искаженной: она уже удалена.

Если вы новичок в C ++, вам нужно убедиться, что вы понимаете время жизни объекта.Это значительно упростит написание этого кода.

Решение состоит в том, чтобы гарантировать, что ваш CString объект не будет уничтожен, пока вы не покончили с ним.Если вам нужно, чтобы объект существовал только внутри вашей функции, вы можете оставить его как временный объект, созданный внутри этой функции.Если вам нужно, чтобы он существовал вне этой функции, вам нужно создать его на более высоком уровне или сохранить указатель на него.

Обратите внимание, что CString объекты неявно , преобразуемый в LPCTSTR.

Таким образом, предполагая, что вам нужен только объект CString, чтобы остаться в живых в пределах вашей функции, вы можете написать следующий код:

{
    // Declare a string literal
    LPCTSTR strValue = L"test";

    // Encrypt the string
    const char* strReturn = MethodCall(strValue);

    // Create a CString object representing the encrypted string
    CStringA myString(strReturn);

    // Do something with myString, like display it in a message box
    // (Remember that it's an ANSI (non-Unicode) string!)
    // ...
    MessageBoxA(NULL, myString, NULL, MB_OK);
    // ...

    // myString (your CString object) gets destroyed here
}
0 голосов
/ 20 марта 2012

Что вы можете сделать, это создать новый объект CStringA и привести его к const char* для финала.Тогда Final будет оставаться действительным до тех пор, пока определена CStringA.

Я бы рекомендовал не использовать CString (или CStringW) для хранилища, к которому вам необходимо получить доступ, используя const char*.

...