.net4 中未调用托管 C++ 静态构造函数

2024-01-03

我最近将我正在处理的项目从 .NET 3.5 迁移到 .NET 4。我使用 C#、托管 C++ 和非托管 C++。

在我的托管 C++(互操作)之一中,我有一个静态构造函数:

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);                      
    }
};

在 .NET 3.5 中一次Dequeue()第一次调用它会触发静态初始化,从而运行静态构造函数。当我迁移到 .NET 4.0 后,静态构造函数就再也没有被调用过。

我知道 .NET 4.0 中的静态初始化发生了变化,但根据我读到的内容,它应该可以正常工作。


在 .NET 中,类型初始值设定项只能在第一次访问字段时调用。这是由[BeforeFieldInit]属性。

我提交了一份错误报告,尽管被标记为“公开”,但该报告仅提供给 Beta 测试人员。

以下是微软的解释,你可能会觉得有帮助:

对于 C++,这是预期的行为。我们用以下方式标记我们的课程BeforeFieldInit,因此 CLR 执行的初始化是正确的。我们没有在 C++/CLI 中提供更改此行为的方法。如果您需要运行类构造函数,您可以调用System.Runtime.CompilerServices.RuntimeHelpers::RunClassConstructor明确地。


由于我们在这里调用该标准,因此 Partition I, 8.9.5 中的行表示:

如果标记为 BeforeFieldInit 那么该类型的初始化方法在第一次访问任何静态字段时或之前执行为该类型定义。

该部分实际上详细介绍了语言实现如何选择来阻止您所描述的行为。 C++/CLI 选择不这样做,而是允许程序员根据需要这样做。

基本上,由于下面的代码绝对没有静态字段,因此 JIT 完全正确,不调用静态类构造函数.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

.net4 中未调用托管 C++ 静态构造函数 的相关文章

随机推荐