2

我希望标题足以帮助解释我遇到的问题。我想一旦我解决了这个问题,我的项目就差不多完成了。请注意,这两个项目都是在 Unicode 下编译的。

我正在使用一个接收 a并返回 a的CLI/C++DLL 。如果我在单步执行时将返回值存储在我的项目中,我可以看到它返回的值是我期望返回的值。LPCTSTRconst char*const char*

现在,如果我执行以下操作:

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

Return 将等于“Xmkk=Asmks”(这是应该的)。此方法对字符串进行加密。问题是当我这样做时CString,最终将等于“ﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮﻮ㹙癞鞮᠀诸²⤐²”。如何在不更改其数据的情况下将其onst char*变成“LPCTSTR

谢谢你。

4

3 回答 3

4

在 CString(Return) 被破坏后(这发生在“构造后的下一行”)“Final”指针指向已释放的内存块(这是内部 CString(Return) 缓冲区)。此时它指向的内存内容是未定义的,取消引用它是未定义的行为。
要安全地使用指向内部缓冲区的指针,您应该确保拥有缓冲区的 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




于 2012-03-20T17:22:13.537 回答
1

正如 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
}
于 2012-03-20T17:38:00.663 回答
0

您可以做的是创建一个新CStringA对象并将其转换const char*为 Final。只要定义了 CStringA,Final 将保持有效。

我建议不要使用CString(或CStringW)存储您需要使用const char*.

于 2012-03-20T17:31:32.873 回答