Managed C++ Static Constructor not called in .net4

泄露秘密 提交于 2020-01-02 18:38:08

问题


I've recently moved a project I'm working on from .NET 3.5 to .NET 4. I'm using C#, Managed C++ and Unmanaged C++.

In one of my Managed C++ (interop) I'm having a static constructor:

public ref class StaticPool : public BaseStaticPools
{
public:
    static StaticPool()
    {                       
        InitializePools();
    }

    static Poolable^ Dequeue()
    {
        return (Poolable^)Dequeue(Poolable::typeid);
    }

private:
    static void InitializePools()
    {                       
        BaseStaticPools::CreatePool(Poolable::typeid);                      
    }
};

In .NET 3.5 once Dequeue() had been called for the first time it would trigger the static initialization, which runs the static constructor. Once I moved to .NET 4.0, the static constructor was never called.

I know there have been changes in static initializations in .NET 4.0, but according to all I read it should work fine.


回答1:


In .NET, type initializers may only be called the first time a field is accessed. This is controlled by the [BeforeFieldInit] attribute.

I filed a bug report, which is only available to beta testers, despite being marked "Public".

Here's the explanation from Microsoft, which you may find helpful:

For C++, this is the intended behavior. We mark our classes with BeforeFieldInit, and so the initialization the CLR is performing is correct. We do not offer a way in C++/CLI to change this behavior. If you require the class constructor to run, you are able to call System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor explicitly.


Since we're invoking the standard here, the line from Partition I, 8.9.5 says this:

If marked BeforeFieldInit then the type’s initializer method is executed at, or sometime before, first access to any static field defined for that type.

That section actually goes into detail about how a language implementation can choose to prevent the behavior you're describing. C++/CLI chooses not to, rather they allow the programmer to do so if they wish.

Basically, since the code below has absolutely no static fields, the JIT is completely correct in simply not invoking static class constructors.




回答2:


Jon Skeet wrote on this topic:

Type initialization changes in .NET 4.0



来源:https://stackoverflow.com/questions/8989003/managed-c-static-constructor-not-called-in-net4

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