无法在需要对象展开修复的函数中使用__try

时间:2018-08-06 06:06:22

标签: c++

我在这里有一个游戏机器人这个循环,该机器人需要__try __except来防止注入代码时的insta崩溃。但是,我收到错误消息:Cannot use __try in functions that require object unwinding fix

我已经仔细研究了该函数内部的所有函数调用,但其中没有一个包含嵌套的__try __except,而且我还在使用/ EHs进行构建。

这是我的代码;

void bot::logic::loop()
{
    while (true)
    {
        __try
        {
            if (bot::logic::should_close())
                exit(33062);

            om::refresh_minions();

            if (local_player::is_threatened())
                local_player::handle_threat();

            if (local_player::is_in_turret())
            {
                utils::move_to_suitable_pos();
                std::this_thread::sleep_for(12s);
            }

            object* localplayer = obj_local_player;
            bot::logic::calculate_buys(localplayer->current_gold);

            obj_manager* manager = (obj_manager*)(m_base + o_obj_manager);
            for (int32_t i = 0; i < manager->highest_index; i++)
            {
                object* this_object = manager->ptrs[i];

                if (this_object)
                {      
                    if (is_minion(this_object) == 3073)
                        if (local_player::object_is_enemy(this_object))
                            if (utils::is_object_mid(this_object))
                                if (is_alive(this_object) == TRUE)
                                    utils::Log("all passed");

                    if (local_player::object_is_enemy(this_object) && utils::is_object_mid(this_object) && is_alive(this_object) == TRUE && is_minion(this_object) == 3073)
                    {
                        object* enemy_minion = this_object;

                        for (int i = 0; i < game::minion_maxed_index; i++)
                        {
                            bot::logic::moving_to_cs_loop(om_ally_minions[i].minion_object, enemy_minion);
                            bot::logic::csing_loop();
                        }
                    }
                }
            }
            std::this_thread::sleep_for(100ms);
        }
        __except (EXCEPTION_EXECUTE_HANDLER) {};
    }
}

任何人都可以告诉我哪些对象“需要平放”以及如何防止该错误吗?

编辑:我发现代码内发生错误;

if (is_minion(this_object) == 3073)
    if (local_player::object_is_enemy(this_object))
        if (utils::is_object_mid(this_object))
            if (is_alive(this_object) == TRUE)
                utils::Log("all passed");

4 个答案:

答案 0 :(得分:3)

无论如何,我建议您将__try / __ except中的代码移至自己的函数中,然后再调用它,这样就可以在其他函数中进行堆栈展开。

例如

void loop()
{
  __try  { loopimpl(); }
  __except(EXCEPTION_EXECUTE_HANDLER) {};
}

void loopimpl()
{
  while (true) { ... }
}

答案 1 :(得分:1)

将__try / __移动到呼叫层次结构的上层除外

void test() {
    myClass m;
    __try
    {
        m.run();
    }
    __except (GenerateDump(GetExceptionInformation())){}
}
int main()
{
    test();
}

结果:错误C2712无法在需要对象展开的函数中使用__try ...

但是:

void test() {
    myClass m;  
    m.run();
}
int main()
{
    __try
    {
        test();
    }
    __except (GenerateDump(GetExceptionInformation())) {}
}

结果:确定

答案 2 :(得分:0)

from the docs

  

错误

     

如果使用/ EHsc和具有结构化功能的函数,则可能会发生C2712   异常处理还具有需要展开的对象   (破坏)。

     

可能的解决方案:

Move code that requires SEH to another function

Rewrite functions that use SEH to avoid the use of local variables and parameters that have destructors. Do not use SEH in constructors
     

或析构函数

Compile without /EHsc

因此,基本上,您需要分离出需要销毁的对象。通常,这意味着将__try中的内容分离到另一个函数中。

答案 3 :(得分:0)

我已经通过一个从 C++11 开始的 labda 函数解决了这个问题。特别适用于 msvc (2015, 2017, ...)。必须使用 /EH* 命令行选项。

std::vector<...> a;

[&]() {
  __try {
    a.resize(...);
    ...
    [&]() {
      std::vector<...> b;
    }();
  }
  __finally {
    ... 
  }
}();

或更通用的变体,例如,在主要:

int main()
{
    std::vector<...> a;
    return [&]() -> int { __try {
        return [&]() -> int {
            std::vector<...> b;
            return 0;
        }();
    }
    __finally {
        // close all handles here...
    }
    return 0;
    }();
}

这样做的一些缺点是您仍然无法返回 c++ 对象,并且必须通过所有 labda 函数将它们分配给 __try 范围之外的最外层范围。

std::string foo()
{
    std::string ret;

    [&]() { __try {
        [&]() {
            // return std::string{"123"}; // error C2712: Cannot use __try in functions that require object unwinding
            ret = std::string{"123"};
        }();
    }
    __finally {
        // close all handles here...
    }
    }();

    return ret;
}

https://godbolt.org/z/Kxxqrc1hh

如果你想在 GCC 下启用 __try/__except/__finally,那么可以看看这样的:http://www.programmingunlimited.net/siteexec/content.cgi?page=libseh