Why does my multithreaded C++ .NET application only crash when executed outside of visual studios?

会有一股神秘感。 提交于 2019-12-05 18:34:58

The program is crashing because formCallback is NULL (and thus core::doCall dereferences a NULL pointer). formCallback is NULL because the Form1 static constructor that initialises it is never run.

You can demonstrate this by adding the following line to the Form1 static constructor:

static Form1() {
    // ... other initialisation ...
    MessageBox::Show(((int) formCallback).ToString("x8"));
}

In Debug builds (or Release run under the VS debugger), a MessageBox will be shown with the value of the function pointer. In a Release build (not under the debugger), this dialog isn't shown because the static constructor isn't run.

The static constructor isn't run because the type is marked BeforeFieldInit. This means that "the type's initializer method is executed at, or sometime before, first access to any static field defined for that type". If there is no access of any static field, then the static constructor is not required to run (and in a Release build, it doesn't).

As per this Connect issue, this is by design. The workaround is to access a static field of your type in the instance Form1 constructor, which will force the static constructor to run, which will initialise formCallback correctly:

static int s_dummy;

public:
    Form1()
    {
        // force static constructor to run now
        s_dummy = 0;

        InitializeComponent();
    }

Alternatively (and what I would recommend), use the Thread class to create a new managed thread; this will avoid the need for the managed delegate, the GCHandle, the formCallback global function pointer, and the static constructor. From that managed thread, you could call into native C++ if you need to execute unmanaged code.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!