c++ /CLI上的值结构实现了一个有where t: struct约束的接口,导致编译器崩溃
本文关键字:struct 约束 where 接口 崩溃 编译器 结构 CLI 实现 c++ 一个 | 更新日期: 2023-09-27 18:02:53
在c++/CLI中实现值类型结构上的接口时遇到问题,其中接口上的一个方法恰好有一个需要ref的方法签名。我相信我使用了正确的语法,但是编译器崩溃了。我让它编译的唯一方法是通过删除where约束。我在c++/CLI中的语法有什么问题,一定是做错了:
解决方案TestSomething.sln:
- 在解决方案中创建c#类库项目,包含一个名为Class1.cs的文件,其内容如下(a)。我将库命名为"Blah"
- 在解决方案中创建c++/CLI控制台应用程序,包含一个名为TestStruct.h的文件,其内容如下(B)。我将控制台项目称为"ValueStructInterfaceIssueCppCli"
- 构建解决方案,它将生成以下错误:
Error 1 Error 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#类库"blah"的项目引用。
teststructure .h (B) Contents
#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);
}
作为另一个测试,我在c++/CLI中使用了"refstruct",这也有效。无论出于何种原因,我不能在c#中使用"where T: struct",然后在c++/CLI中实现值结构。看起来很奇怪。我相信我在c++/CLI中使用了正确的格式:
virtual void DoSomething(TestStruct% source)
%对于通过引用传递值类型是正确的,它应该很好,但我不明白为什么它不能编译。
对于简单地删除c#中的where约束,我也有一些顾虑。如果T碰巧是一个对象,那么语法TestStruct%源是不正确的,它必须是TestStruct%^当T是int时,例如"%^"不会工作,除非我错过了一些东西
更新! !
rob在评论中提到的一些事情给了我一个想法。我修改了代码,为T使用了不同的结构,如下所示:teststructure .h (B) Contents
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)
Copy(ref TestStruct source) { /* do some copying */ }
在您的实现之上添加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;
};
};
}
不是真的,但是Lucas和ebyrob在下面的评论中给了我一些想法:
基于用int或其他结构体替换TestStruct的发现编译器不再崩溃....说明更多的只是一些编译器问题。为了证明这一点,我使用了4.6.1而不是4.0,看看它是否被修复了
重新尝试了我在帖子中提到的原始测试。它DOES在。net 4.6.1和C+/CLI中编译得很好。@Lucas ->看起来像一个编译器错误。也不会在VS 2010明显修复,但我知道什么。至少在4.6.1中修复。
所有这些理论都是由ebyrob带来的,所以谢谢ebyrob把我引向了另一个方向,尽管这是Lcuas指出的完全有效的语法,但仍然让我走上了道路。
再次感谢大家