我希望标题足以帮助解释我遇到的问题。我想一旦我解决了这个问题,我的项目就会完成。请注意,两个项目都是在Unicode下编译的。
我正在处理一个CLI/C++
DLL,它接收LPCTSTR
并返回const char*
。如果我在项目的const char*
中存储了返回值,并且单步执行,我可以看到它返回的值是我期望返回的值。
现在,如果我执行以下操作:
LPCTSTR strValue = L"test";
const char* Return = MethodCall(strValue);
LPCTSTR Final = CString(Return);
返回将等于“Xmkk = Asmks”(这应该是什么)。此方法加密字符串。问题是当我做CString
时,Final将等于“وووووووووووووووووووووووووووووووووووووووووووو㹙㹙”“”“”“”如何在不更改数据的情况下将onst char*
变为LPCTSTR
谢谢。
答案 0 :(得分:4)
在CString(Return)被破坏后(这种情况发生在“构造完成后的下一行”)“最终”指针指向被处理的内存块(内部CString(返回)缓冲区)。此时,它指向的内存内容未定义,并且取消引用它是未定义的行为
要使用指向内部缓冲区的指针,你应该确保拥有缓冲区的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 :(得分:1)
正如vnm所提到的,你通过在第3行调用它的构造函数来创建一个临时的CString
对象,然后该对象立即被销毁。这会释放它用于缓冲区的内存块,这意味着任何访问存储在该内存中的数据的尝试都将是未定义的行为。这就是你的字符串看起来乱码的原因:它已被删除。
如果您是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
}
答案 2 :(得分:0)
您可以做的是创建一个新的CStringA
对象并将其转换为const char*
以进行最终。只要定义了CStringA,Final就会保持有效。
我建议不要使用CString
(或CStringW
)来存储您需要使用const char*
访问的内容。