【问题标题】:C++ program crashing on Python script callC++ 程序在 Python 脚本调用时崩溃
【发布时间】:2014-07-21 21:26:13
【问题描述】:

我正在尝试发送一个运行特定 python 脚本的命令:但是,只要程序到达执行行,就会发生这种情况:

GameServer.exe 中 0x69bd1f16 处未处理的异常:0xC0000005:访问冲突读取位置 0x46f520ca。

程序停止响应并崩溃。这是有问题的方法:

void ScriptManager::runScript(std::string scriptName, std::string args[])
{
    std::string py = "python " + scriptName;
    std::cout << py << std::endl;
    for(int i = 0; i < args->length(); i++)
    {
        py += " " + args[i];
        std::cout << py << std::endl;
    }
    std::cout << py << std::endl;

    std::system(py.c_str());

}

这会调用上面的函数:

void DBFactory::dbRegisterUser(std::string username, std::string password)
{
    ScriptManager script;
    std::string data[] = {username, password};

    script.runScript("Python.py", data);
}

据我所知,该脚本没有运行。如果有帮助,我也可以发布脚本。

【问题讨论】:

  • args-&gt;length() 上的循环看起来不对。这是第一个字符串的长度,即args[0]。你能显示调用这个函数的代码吗?
  • 是的。我已经用这个函数更新了帖子。
  • 您需要将数组的长度传递给函数,或者使用可以推断出数组长度信息的函数模板。见stackoverflow.com/questions/1328223/…
  • Hm... 看来命令构造正确(python Python.py arg1 arg2),但执行抛出错误。除非我误解了你在说什么?
  • args-&gt;length()args[0]的长度,即username。不是args 中的元素数。

标签: python c++ integration


【解决方案1】:

这就是问题所在:

for (int i = 0; i < args->length(); i++)
{
    py += " " + args[i];
    std::cout << py << std::endl;
}

args-&gt;length() 等价于args[0].length();即您正在获取数组中第一个字符串的长度并将其用作索引。经过两次迭代后,您将访问数组的末尾。最好的解决方案是(所有示例均未测试):

  1. 使用std::array(仅限C++11):

    void DBFactory::dbRegisterUser(std::string username, std::string password)
    {
        ScriptManager script;
    
        script.runScript("Python.py", {username, password});
    }
    
    void ScriptManager::runScript(std::string scriptName, std::array<std::string, 2> args)
    {
        std::string py = "python " + scriptName;
        std::cout << py << std::endl;
        for (std::string s : args)
        {
                py += " " + s;
                std::cout << py << std::endl;
        }
        std::cout << py << std::endl;
    
        std::system(py.c_str());
    }
    
  2. 使用std::vector(示例使用C++03):

    void DBFactory::dbRegisterUser(std::string username, std::string password)
    {
        ScriptManager script;
        int tmp[2] = {username, password};
    
        script.runScript("Python.py", std::vector<std::string>(&tmp[0], &tmp[0]+2));
    }
    
    void ScriptManager::runScript(std::string scriptName, std::vector<std::string> args)
    {
        std::string py = "python " + scriptName;
        std::cout << py << std::endl;
        for(std::vector<std::string>::iterator it = args.begin(); it != args.end(); it++)
        {
            py += " " + *it;
            std::cout << py << std::endl;
        }
        std::cout << py << std::endl;
    
        std::system(py.c_str());
        }
    
  3. 将数组大小作为参数传递:

    void DBFactory::dbRegisterUser(std::string username, std::string password)
    {
        ScriptManager script;
    
        script.runScript("Python.py", {username, password}, 2);
    }
    
    void ScriptManager::runScript(std::string scriptName, std::string args[], int size)
    {
        std::string py = "python " + scriptName;
        std::cout << py << std::endl;
        for(int i=0; i<size; i++)
        {
            py += " " + args[i];
            std::cout << py << std::endl;
        }
        std::cout << py << std::endl;
    
        std::system(py.c_str());
    }
    

我个人更喜欢示例 1,并且会像瘟疫一样避免示例 3。示例 2 运行良好,但可能不如示例 1 快。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-09-05
    相关资源
    最近更新 更多