【问题标题】:Stackoverflow exception raised when instanciating an unmanaged class from a clr gui从 clr gui 实例化非托管类时引发 Stackoverflow 异常
【发布时间】:2018-10-09 22:46:38
【问题描述】:

我正在编写一个 c++/clr gui 来包装我为测试目的而编写的一些非托管 c++ 代码。

我使用一个名为HolderOfUnmanagedStuff 的代理类来实例化我在 clr gui 中需要的几个非托管对象。

#pragma once
#include "foo.h"
namespace fooCore
{
    public class HolderOfUnmanagedStuff
    {
    public:
        HolderOfUnmanagedStuff()
        {
            foos = std::vector<fooCore::foo>();
        }
        ~HolderOfUnmanagedStuff() { }
    public:
        std::vector<fooCore::foo> foos;
        void addFoo(std::string & fileName)
        {
            whatever code on the first line    // <-- System.StackOverflowException

            foo myfoo(FileName);  // <--- when I comment those 2 lines no exception
            foos.push_back(foo);  //      but exception when I comment only this one
        }
        otherUnmanagedMembers ...
    };
}

我的 foo 类使用从文件中读取对象的构造函数:

#pragma once
namespace fooCore
{    
    class foo
    {
    public:
        foo();
        foo(std::string & fileName);
        ~foo();

         fooMembers...
    };
}

每当我尝试实例化 foo 类时,都会收到 Stack OverFlow 异常,函数的第一行有一个中断。

调用堆栈只显示逻辑调用层次结构:一个按钮事件,然后是对 addFoo 函数的调用,仅此而已

我尝试了多种解决方案,重写了每个构造函数,检查了非托管/托管冲突、指针、地址、引用。

我学到了很多东西(很明显,因为我已经有 15 年没有编写非托管代码了)但我找不到问题所在。有什么想法吗?

编辑

我尝试了一些方法:

  1. 向我的 Holder 添加了一个 foo 成员:好的

  2. 试图在构造函数中定义该成员:构造函数中的异常

  3. 在 addFoo 函数中将 foo 成员推入 foo 向量:OK

  4. 在 addFoo 中定义 foo 成员:异常

以下代码显示了我所做的 4 个测试:

public class HolderOfUnmanagedStuff
{
    public:
        HolderOfUnmanagedStuff()
        {
            ...
            memberFoo = foo(); // TEST 2 : SOF exception on the first line of the constructor
        }
        ~HolderOfUnmanagedStuff() { }
    public:
        foo memberFoo;    // TEST 1 : No exception with that line 
        std::vector<fooCore::foo> foos;
        void addFoo(std::string & fileName)
        {
            ...               
            foos.push_back(memberFoo);  // TEST 3 No exception with that line
            memberFoo = foo();  // TEST 4 SOF on the first line of the function
        }
        otherUnmanagedMembers ...
    };

【问题讨论】:

  • Foo 是否是托管类?上次我使用 C++/CLI(很久很久以前)时,您的代码无效:非托管类(如 Foo 似乎是)无法将托管参数作为 System.String^。但也许从那以后情况发生了变化
  • 我认为你的 foo::foo(System::String ^) 构造函数中有一个错误,你没有包含在问题中。此外,最好将 push_back 替换为 emplace_back,以避免制作不必要的 foo 副本。
  • 嗯,这很可能是构造函数中的错误,也很可能是其中使用了托管对象,但我不会得到更明确的错误吗?如果是这样,为什么要编译?当我犯菜鸟托管/非托管错误时,编译时会出现很多错误。
  • 你检查过你的 foo 类是可复制和可移动的吗?它必须是在容器中使用的那样。
  • 我编辑了这个问题以澄清一个事实:我在实例化 foo 对象的任何函数的第一行上都出现异常,无论该实例化在我的代码中的何处

标签: c++ stack-overflow unmanaged managed


【解决方案1】:

异常是由于我的 foo 类对于堆栈来说太大了。

我修改了我的代码,以便默认构造函数在数据段(在堆上)中声明每个 foo 对象。不再有堆栈溢出,数据结构更符合逻辑。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 2021-05-24
    • 1970-01-01
    • 2011-12-15
    • 1970-01-01
    相关资源
    最近更新 更多