我尝试使用python脚本从c ++项目运行blender。为此我使用_popen
。它在启动时因blender is not responding
而崩溃 - 但错误。
我有一些子文件夹,其中生成了我的程序的.exe,并且Visual Studio配置为在此位置开始相对路径。看起来像这样:
Debug
|--- MyProgram.exe
|
|--- blender-2.72b-windows64
|
|--- Resources
| |--- GenericHeadMesh.blend
|
|--- python
| |--- global.py
| |--- local.py
|
|--- Output
我为命令构建一个字符串(使相对路径成为绝对路径)。
获取绝对路径的函数(这是相当草率的,但它并不意味着 发货了,这是一个研究项目。)
std::string PathHandler::GetBlenderPath()
{
if (blenderPath.empty())
blenderPath = GetFullPath(R"(blender-2.72b-windows64\)");
return blenderPath;
}
std::string PathHandler::GetOutputPath()
{
if (outputPath.empty())
outputPath = GetFullPath(R"(Output\)");
return outputPath;
}
std::string PathHandler::GetResourcesPath()
{
if (resourcesPath.empty())
resourcesPath = GetFullPath(R"(Resources\)");
return resourcesPath;
}
std::string PathHandler::GetPythonPath()
{
if (pythonPath.empty())
pythonPath = GetFullPath(R"(python\)");
return pythonPath;
}
std::string PathHandler::GetFullPath(const std::string relPath)
{
char full[_MAX_PATH];
_fullpath(full, relPath.c_str(), _MAX_PATH);
return EscapeString(std::string(full));
}
std::string PathHandler::EscapeString(const std::string input)
{
std::regex toReplace("\\\\");
std::string output(input.begin(), input.end());
output = std::regex_replace(output, toReplace, "\\\\");
return output;
}
我的子处理函数看起来像这样(有一些调试):
void PythonConnector::runCommand(const std::string &command)
{
FILE* output = _popen(command.c_str(), "r");
qDebug() << "c_str(): " << command.c_str();
qDebug() << _pclose(output);
}
我正在构建这样的字符串:
std::string blenderPath = pH.GetBlenderPath() + "blender.exe";
std::string meshGlobalPath = pH.GetResourcesPath() + "GenericHeadMesh.blend";
std::string pythonGlobalPath = pH.GetPythonPath() + "global.py";
std::string globalCommand = "\"\"" + blenderPath + "\" --background \"" + meshGlobalPath + "\" --python \"" + pythonGlobalPath + "\" -- \"" + pH.GetOutputPath() + "\"\"";
第一个和最后一个引用显然是字符串,每个路径都有一个转义引用来捕获带空格的路径,我不得不在开头和结尾放入另一个转义引号,否则它甚至不会启动blender (或至少尝试)。
我需要一次又一次地对blender进行子处理(应用一些更改,存储结果,使用这些更改计算并再次应用),所以我需要 实际上等待子进程像_popen一样完成的某种子处理方式。
路径看起来像这样(来自runCommand()
的调试):
c_str():“”C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \项目\ QtTest \ 64 \调试\搅拌机-2.72b-windows64 \ blender.exe” --background“C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \ Projects \ QtTest \ x64 \ Debug \ Resources \ GenericHeadMesh.blend” --python“C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \ Projects \ QtTest \ x64 \ Debug \ python \ global.py” - “C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \项目\ QtTest \ 64 \调试\输出\ “”
_pclose()给出一个退出代码0(没有额外的“1”)。
(仅globalCommand
的调试将以三个引号开始和结束,但使用c_str()的调试仅使用两个。
现在它的作用是尝试启动blender,然后崩溃并发送blender is not responding
消息。
如果我调试,我在msvcr120.dll和退出代码3获得一个源。(这可能意味着找不到路径或者根据任务管理器没有足够的内存。 )我无法获得有关此内容的更多信息,无法加载.pdb。
如果我手动在cmd提示符中键入等效命令,它就可以正常工作。看起来像这样:
“C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \项目\ QtTest \ 64 \调试\搅拌机-2.72b-windows64 \ blender.exe” --background“C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \ Projects \ QtTest \ x64 \ Debug \ Resources \ GenericHeadMesh.blend” --python“C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \ Projects \ QtTest \ x64 \ Debug \ python \ global.py” - “C:\ Users \ Gunnar \ Documents \ Visual Studio 2013 \项目\ QtTest \ 64 \调试\输出\“
我不知道造成这个问题的原因。这是我的程序没有的一些权利吗?我可以将数据写入Output
- 文件夹中的.txt文件,没有问题。
我正在使用blender 2.72b,Visual Studio 2013和Windows 7 64bit。
编辑:
似乎问题与项目/它的设置/某事有关。我创建了一个新项目作为测试,这非常好用:
std::string command = "\"\"C:\\Users\\Gunnar\\Documents\\Visual Studio 2013\\Projects\\QtTest\\x64\\Debug\\blender-2.72b-windows64\\blender.exe\" --background \"C:\\Users\\Gunnar\\Documents\\Visual Studio 2013\\Projects\\QtTest\\x64\\Debug\\Resources\\GenericHeadMesh.blend\" --python \"C:\\Users\\Gunnar\\Documents\\Visual Studio 2013\\Projects\\QtTest\\x64\\Debug\\python\\global.py\" -- \"C:\\Users\\Gunnar\\Documents\\Visual Studio 2013\\Projects\\QtTest\\x64\\Debug\\Output\\\"\"";
FILE* f = _popen(command.c_str(), "r");
_pclose(f);
我不知道造成这个问题的原因。我更改了一些设置相对路径开始的地方。我已经恢复了,但它没有改变任何东西。我想我会创建一个新项目并复制内容。该项目似乎总体上存在一些问题。它在某些时候变得很慢并且不时地落在计算机上(给出那个小的检查图标)。