ref and out parameters

  • Thread starter Thread starter SamoK
  • Start date Start date
S

SamoK

Hy!

I'd like to know how can I use ref and out parameters in c++.
I'd like to send (from C#) to my C++.net function a variable by reference,
so I could change it in my c++.net function.

And all I find about this topic is about C#.

thanks
- Samo
 
SamoK said:
Hy!

I'd like to know how can I use ref and out parameters in c++.
I'd like to send (from C#) to my C++.net function a variable by reference,
so I could change it in my c++.net function.

And all I find about this topic is about C#.

Managed C++ doesn't provide those keywords, which are C# features, not .NET
features. AFAIK, it isn't possible to write a C++ function that C# views as
having out parameters, but you can write a C++ function that C# views as
having ref parameters. For example:

// a1.cpp

#using <mscorlib.dll>
using namespace System;

public __gc struct X
{
int x;

X()
: x(2)
{
}

void f1(int __gc * x)
{
++*x;
}

static void f2(X __gc * __gc * p)
{
X* q = new X;
q->x = (*p)->x;
++q->x;
*p = q;
}
};

// a.cs

using System;

public class MyClass
{
static void Main()
{
X x = new X();
X x2 = x;
int i = 0;
Console.WriteLine("i = {0}", i);
x.f1(ref i);
Console.WriteLine("i = {0}", i);
Console.WriteLine("x RefEquals x2 == {0}",
Object.ReferenceEquals(x, x2));
Console.WriteLine("x.x = {0}", x.x);
Console.WriteLine("x2.x = {0}", x2.x);
X.f2(ref x);
Console.WriteLine("x RefEquals x2 == {0}",
Object.ReferenceEquals(x, x2));
Console.WriteLine("x.x = {0}", x.x);
Console.WriteLine("x2.x = {0}", x2.x);
}
}

C>cl -LD -clr -W3 a1.cpp
C>csc a.cs /r:a1.dll
C>a
i = 0
i = 1
x RefEquals x2 == True
x.x = 2
x2.x = 2
x RefEquals x2 == False
x.x = 3
x2.x = 2
 
Hi Doug,

Managed C++ doesn't provide those keywords, which are C# features, not ..NET
features. AFAIK, it isn't possible to write a C++ function that C# views as
having out parameters,

Actually, it is perfectly possible. The only difference between a ref and an
out argument in C# is the presence of an out attribute on the generated
metadata, which can be easily generated by applying the
System::Runtime::InteropServices::OutAttribute attribute to the parameter in
the method's signature.
 
Tomas said:
Actually, it is perfectly possible. The only difference between a ref and an
out argument in C# is the presence of an out attribute on the generated
metadata, which can be easily generated by applying the
System::Runtime::InteropServices::OutAttribute attribute to the parameter in
the method's signature.

Right you are. Before posting I looked at a C# exe in ildasm and it showed
these functions:

public void f1(ref int x)
{
}

public void f2(out int x)
{
x = 2;
}

as:

f1 : void(int32&)
f2 : void(int32&)

Opening the functions in disassembly windows gave:

.method public hidebysig instance void f1(int32& x) cil managed
.method public hidebysig instance void f2([out] int32& x) cil managed

There's that [out] attribute. :)

So, my C++ example code could be modified as:

using namespace System::Runtime::InteropServices;
....
void f1([Out] int __gc * x)
{
*x = 2;
}

Then the C# side would recognize and respect the out parameter. However, the
C++ side would not provide C#-like [out] semantics for C++ code; it would
merely emit the attribute metadata.
 
Back
Top