我使用 Visual Studio 构建了一个测试项目(CxxTest)并立即通过构建后事件执行它。这很有效,并且已经这样做了很长时间。现在,与从命令行 shell 手动执行相比,我在构建后事件的执行中有不同的行为。与手动启动 exe 或使用 Visual Studio 调试器相比,以下代码在构建后事件中的行为有所不同:
// getValueFromStruct returns empty string when executed
// as post build event, but returns correct value when executed manually
std::string expectedValue1("Val_1");
TS_ASSERT_EQUALS(expectedValue1, getValueFromStruct(res1));
这是调用的辅助函数:
std::string getValueFromStruct(tResult pResult)
{
std::string result = "";
if (pResult.pCharDetails != NULL)
{
for (int i=0; i < pResult.iNumResults; i++)
{
result.append(1, static_cast<char>(pResult.pCharDetails[i].wChar1));
}
}
// also the cout of the result is empty when executed from
// build event, but is filled with data when in shell
std::cout << ++callCount << " : " << result<< std::endl;
return result;
}
似乎只有在同一方法中为多个 tResult 实例调用 getValueFromStruct(tResult) 时才会出现问题。
两种方式之间是否存在环境、运行时库或其他方面的差异?Visual Studio 是否在为构建事件操作命令行环境?
该问题仅出现在Release 和 x64 模式中。它只出现在我的机器上,而不是在构建服务器上。但是,当像服务器一样通过构建脚本在我的机器上构建时也会出现这种情况。
我找到了 3 种绕过问题的方法:
- 通过使用临时变量而不是直接将函数的结果作为参数传递。
- 禁用 test.exe 的优化
- 将 test.exe 的“内联函数扩展”设置为“禁用 /Ob0”。
但它没有解释为什么它在构建事件和常规命令行中的行为不同。