C#6 / C ++ ref关键字错误

时间:2014-11-18 09:18:15

标签: c# c++ interop roslyn ref

我使用现有的解决方案尝试了VS2015,并且我得到了一些有效的新错误(比如编译器之前没有捕到的无法访问的代码),但是我也在这一行上遇到错误:

bool bWasAlreadyLocked = false;
oEnv.LockDoc(oWarnings, oEventDoc, ref bWasAlreadyLocked);

我收到以下错误:

  

错误CS1503参数3:无法转换为' ref bool [mscorlib,   Version = 4.0.0.0,Culture = neutral,PublicKeyToken = b77a5c561934e089]'至   ' ref bool [mscorlib,Version = 4.0.0.0,Culture = neutral,   公钥= b77a5c561934e089]'

我不明白为什么它会抛出那个错误,显然类型确实匹配。这是新编译器中的错误还是ref关键字的行为发生了变化?

这种情况下的函数是一个C ++函数,它使用从c ++类派生的c#类导入C#。它的签名就是:

void CBkgDocEnvX::LockDoc(
CFIWarningList ^oWarnings,
CBaseDoc ^oBaseDoc,
// Output
bool %rbWasAlreadyLocked)

最好提一下,我现在选择将VS2013 c ++编译器用于解决方案中的c ++源代码,因此c ++端应该与以前相同。我的猜测是c#和c ++之间的互操作发生了变化。

4 个答案:

答案 0 :(得分:1)

你应该检查这一点,以确定。

  1. 只能通过引用传递L值。 L值是可能出现在赋值左侧的变量和其他表达式。这些包括本地,字段访问,指针解引用和数组元素访问。 L值不包括属性访问,它们没有可识别的机器地址,也不包括受CLR限制的只读字段。
  2. 参考参数不能是扩展方法的目标。对于值类型,扩展方法调用很昂贵,因为“this”参数是按值复制的。这也意味着值类型不能具有可变扩展方法。这与实例方法形成鲜明对比,后者通过引用传递值类型“this”参数。
  3. 参数参数不能用于运算符重载函数。
  4. 您可以找到更多信息here

答案 1 :(得分:1)

当两个项目的类型不兼容时,我会遇到这类编译器错误。通常Visual Studio允许我添加对可移植类库项目(或.NET 4.0项目)的引用,即使引用项目的.NET配置文件类型不支持被引用的程序集。

最常见的情况是使用.NET 4.0项目并尝试引用可在其配置文件设置中指定.NET 4.5的可能类库项目,而不是旧的.NET 4版本。当我从.NET 4.0项目引用PCL程序集时,我继续获得完整的intellisense支持(例如,当编辑源代码时,intellisense将显示所引用的程序集中包含的所有名称空间,类和属性)但是在编译时我得到了你得到的同样的错误;更具体地说,当我编译解决方案时,编译指示库不匹配,但列出了它所说的完全相同的库,版本和公钥。

检查项目属性,验证它们是否兼容。

答案 2 :(得分:1)

事实证明,可以通过向参数显式添加out属性来修复此错误。

[Out]添加到ref参数显然有助于新的C#编译器识别这些类型是相同的并接受它们。我们的互操作解决方案中的方法现在看起来像这样:

using namespace System::Runtime::InteropServices;

...

virtual void LockDoc(
   CFIWarningList ^oWarnings,
   CBaseDoc ^oBaseDoc,
// Output
   [Out] bool %rbWasAlreadyLocked
   ) override;

答案 3 :(得分:0)

您可以尝试使用Object数据类型而不是Boolean。之后,您可以将其解析为布尔值。