C#6/C++ ref keyword error

1.1k Views Asked by At

I tried VS2015 with my exisiting solution and I get some valid new errors (like unreachable code that the compiler didn't catch before), but I also get an error for example on this line:

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

I get the following error:

Error CS1503 Argument 3: cannot convert from 'ref bool [mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]' to 'ref bool [mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]'

I cannot see why it would throw that error, obviously the types do match. Is this a bug in the new compiler or has the behaviour of the ref keyword changed?

The function in this case is a C++ function which is imported to C# using a c# class derived from the c++ class. It's signature is this:

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

It might be good to mention that I opted to use the VS2013 c++ compiler for the c++ sources in the solution for now, so the c++ side should be the same as before. My guess is that something in the interop between c# and c++ changed.

4

There are 4 best solutions below

0
On BEST ANSWER

It turns out that this error can be fixed by explicitly adding an out attribute to the parameter.

Adding [Out] to the ref parameter apparently helps the new C# compiler to recognize that these are the same types and accept them. The methods in our interop solution now look like this:

using namespace System::Runtime::InteropServices;

...

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

I get those kinds of compiler errors when two projects are of incompatible types. Often times Visual Studio will allow me to add a reference to a Portable Class Library project (or .NET 4.0 project) even when the assembly being referenced is not supported by the referencing project's .NET profile type.

The most common occurrence for me is when using a .NET 4.0 project and trying to reference a Probable Class Library project that specifies .NET 4.5 in its profile settings rather than the older .NET 4 version. When I reference the PCL assembly from my .NET 4.0 project I continue to get full intellisense support (e.g. when editing the source code intellisense will display all the namespaces, classes and properties contained inside the assembly being referenced) But at compile time I get the same kind of error you're getting; more specifically when I compile the solution the compile indicates a library mismatch, but lists the exact same library, version, and public key it says it's looking for.

Check the project properties, verify they're compatible.

1
On

You should check this point just to be sure.

  1. Only L-values may be passed by reference. L-value are variables and other expressions that may appear in left-hand side of an assignment. These include including locals, field accesses, pointer dereferences, and array element accesses. L-values do not include property accesses, which do not have an identifiable machine address, nor do they include read-only fields, which are restricted by the CLR.
  2. Ref parameters can not be the target of an extension method. Extension methods calls are expensive for value types, because the “this” parameter is copied by value. This also means that value types can’t have mutable extension methods. This is in direct contrast to instance methods, which pass the value type “this” parameter by reference.
  3. Ref parameters can not be used in operator overloading functions.

You can find more information here.

1
On

You could try using an Object data type instead of Boolean. After that you could parse it to Boolean.