C ++ / CLI on value struct实现了一个具有where t:struct约束的接口崩溃了编译器

时间:2016-08-17 19:08:38

标签: c# .net c++-cli

在C ++ / CLI中对值类型struct实现接口时出现问题,其中接口上的某个方法恰好具有需要ref的方法签名。我使用了正确的语法,但是编译器崩溃了。我得到编译的唯一方法是删除where约束。我在C ++ / CLI中的语法有什么问题必须做错事:

Solution TestSomething.sln:

  1. 在解决方案中创建C#类库项目,该项目包含一个名为Class1.cs的文件,其内容如下(A)所示。我打电话给图书馆" Blah"
  2. 在解决方案中创建C ++ / CLI控制台应用程序,其中包含一个名为TestStruct.h的文件,其中包含以下内容(B)。我打电话给控制台项目" ValueStructInterfaceIssueCppCli"
  3. 构建解决方案会产生以下错误:
  4.   

    错误1错误C1001:编译器中发生内部错误。 f:\ valuestructinterfaceissuecppcli \ TestStruct.h 22 1 ValueStructInterfaceIssueCppCli

    在C#中我有一个非常简单的界面,这是在一个C#类库项目中,字面上只是一个文件。

    Class1.cs(A)内容

    using System;
    
    namespace Blah
    {
        public interface IHoopie<T> where T : struct
        {
            void DoSomething(ref T source);
        }
    }
    

    然后我在C ++中的值结构上实现这个接口,很简单:

    这是在C ++ / CLI控制台应用程序中,带有对C#类库的项目引用&#34; blah&#34;在同样的解决方案中。

    TestStruct.h(B)内容

    #pragma once
    using namespace System;
    
    namespace Blah
    {
    public value struct TestStruct : public IHoopie<TestStruct> 
    {
    public:
        double X;
        double Y;
        double Z;
    
        virtual void DoSomething(TestStruct% source)
        {
            X = 1;
            Y = 2;
            Z = 3;
        };
    };
    }
    

    然而,当我尝试在VS 2010(sp1)中的C ++ / CLI中实现接口编译器崩溃时,我也尝试在VS 2015(更新3)中编写同样的东西。

      

    错误2错误C1001:编译器中发生内部错误。 .. \ valuestructinterfaceissuecppcli \ TestStruct.h 22 1 ValueStructInterfaceIssueCppCli

    我需要将我的接口限制为只是值类型,但是作为一个测试,我删除了C#接口中的where约束,就像这样和C ++代码一样,然后遵从编译就好了:

    public interface IHoopie<T> 
    {
        void DoSomething(ref T source);
    }
    

    作为另一项测试,我使用了&#34; ref struct&#34;在C ++ / CLI中也是如此。无论出于何种原因,我都不能使用&#34;其中T:struct&#34;在c#中,然后在值结构上的C ++ / CLI中实现它。看起来很奇怪。我相信我在C ++ / CLI中使用了正确的格式:

    virtual void DoSomething(TestStruct% source)
    

    %对于通过引用传递值类型是正确的它应该没问题,但我不知道为什么它无法编译。

    我也有一些担心只是删除C#中的where约束。如果T碰巧是一个对象,那么语法TestStruct%source是不正确的,它必须是TestStruct%^并且当T是一个int时,例如&#34;%^&#34;除非我错过了什么,否则不会工作

    更新!!!

    ebyRob在评论中提到了一些给我一个想法的东西。我更改了代码以使用不同的T结构,如下所示:

    TestStruct.h(B)内容

    public value struct SomeStruct
    {
    public:
        double x;
    };
    
    public value struct TestStruct : public IHoopie<SomeStruct> 
    {
    private:
        double last_;
    
    public:
        double X;
        double Y;
        double Z;
    
        virtual void DoSomething(SomeStruct% source)
        {
            X = 1;
            Y = 2;
            Z = 3;
        };
    };
    

    修复了编译器崩溃....有趣。需要弄清楚这一点。如果这是答案,将回复。我的猜测(而不是一个好的)是在C ++ / CLI中,在.h文件中使用结构作为自己的声明中的T有一些问题吗?这可能是使编译器崩溃的原因。

    请记住C#,这是完全合乎逻辑的。我在结构定义中说,我希望TestStruct实现一个名为DoSomething的方法,该方法通过引用获取自身的值类型。在上下文中,这可能是一个可能的用例(假设DoSomething被称为复制)

    Copy(ref TestStruct source) { /* do some copying */ }
    

2 个答案:

答案 0 :(得分:0)

不是真的回答,但是Lucas和ebyrob在评论中给了我一些想法:

基于调查结果,用int替换TestStruct或其他一些结构编译器不再崩溃....表明更多只是一些编译问题。为了证明这一点,我使用4.6.1而不是4.0来查看它是否已修复

  

重新尝试了我在帖子中提到的原始测试。 DOES 在C ++ / CLI中的.NET 4.6.1上编译得很好。 @Lucas - &gt;看起来像是一个编译器错误。也不会在VS 2010中修复,但我知道什么。至少在4.6.1中修复。

这里所说的所有理论都是由ebyrob带来的,所以感谢ebyrob引导我向另一个方向看,即使这是完全有效的语法,正如Lcuas指出的那样,仍然让我走上了正轨。

再次感谢所有

答案 1 :(得分:0)

在您的实现之上添加IHoopie实现似乎可以避免编译器错误。我不知道为什么。

#pragma once
using namespace System;

namespace Blah
{
public value struct HoopieAdapter : public IHoopie<int> {
    public: virtual void DoSomething(int% source) {}
};

public value struct TestStruct : public IHoopie<TestStruct> 
{
public:
    double X;
    double Y;
    double Z;

    virtual void DoSomething(TestStruct% source)
    {
        X = 1;
        Y = 2;
        Z = 3;
    };
};
}