Windows API 和字符串连接

Windows API and String concatenation

我对 C++ 和 Windows API(来自 Java 背景)比较陌生,我只是在玩 Windows API 调用 MessageBox 和其他简单函数,直到我尝试将连接的字符串从自定义函数传递到 MessageBox 时,我注意到生成的 window.[=21= 中有一个奇怪的输出]

这是可疑函数:

const char* addFoo(const char* strInput)
{
    return ("foo-" + std::string(strInput)).c_str();
}

它只是 returns 原始输入,前面添加了 foo-。 (我希望我没有在那里做任何令人难以置信的错误)

在 main 中,我首先调用了两次 MessageBox,但没有调用该函数,而是即时进行所有计算,然后调用该函数:

const char* a = "bar";
MessageBox(NULL, ("foo-" + std::string(a)).c_str(), "The Foobar Experiment", MB_OK);
MessageBox(NULL, addFoo(a), "The Foobar Experiment", MB_OK);

这是我通过即时进行字符串连接(案例 1)得到的结果:

调用函数addFoo得到的结果(案例2):

有谁知道为什么我使用 addFoo 函数在生成的 window 上得到这些不可读的字符?提前致谢,很抱歉 post.

const char* addFoo(const char* strInput)
{
    return ("foo-" + std::string(strInput)).c_str();
}

这个 returns 一个指向本地临时字符串的指针,它的内存会在您的消息框显示时释放。

在您的情况下用 std::string 替换它:

std::string addFoo(const char* strInput)
{
    return std::string("foo-") + strInput; // not sure about the syntax here
}

然后,std::string 对象会正确管理其内存,并使字符串指针保持活动状态足够长的时间,以便消息框显示它。您需要包含 <string> 才能定义它。

那么,您可以使用:

std::string temp = addFoo( a );
MessageBox(NULL, temp.c_str(), "The Foobar Experiment", MB_OK);

您的代码中有两个根本性的错误,一个与 C++ 相关,另一个与 Windows 相关。

首先,您正在 return 指向本地实体的指针,即 c_str() 的 return 值,它是一个指针。返回指向局部变量的指针是未定义的行为。你想要做的是return一个字符串,而不是一个指针。在 C++ 中,有一些字符串类型,例如 std::stringstd::wstring,它们实现了正确的复制语义,这些语义是安全无误地 returned 对象所必需的。

#include <string>
std::string addFoo(const char* strInput)
{
    return "foo-" + std::string(strInput);
}

您的代码的第二个错误是,在 Windows 世界中,您基本上有两种类型的字符类型应用程序。您有 MBCS 申请和 Unicode 申请。

如果您构建了一个 Unicode 应用程序,您对 MessageBox 的调用将无法编译成功,因为 MessageBox 采用宽字符串,而不是基于字符的字符串。在这种情况下,要使用的正确字符串类型是 std::wstring.

您很可能构建了一个 MBCS 应用程序,这在当今时代变得非常罕见。