Out parameters, VB and C#

M

Michi Henning

Hi,

I'm generating both VB and C# code from language-independent interface
definitions, which is why I'm raising this issue. (The problem apppears
to be somewhat esoteric, but it is real in my situation and is about
more than just convenience.)

C# has the notion of an out parameter (which is different
from pass by value and pass by reference), but VB only understands
pass by value and pass by reference. This means that parameters that
notionally are out parameters end up as ByRef parameters in VB.
I would like to find a way to have VB source code produce parameters
that look like out parameters to C#.

Here is a very simple example. Suppose I have the following in VB:

' VB:
Public Sub setToFortyTwo(ByRef i As Integer)
i = 42
End Sub

I bundle this method into an assembly that I call from C#.
As it stands, I can call the method as:

// C#:
int i = 0; // Must initialize, because call is by reference
setToFortyTwo(ref i);

What I would like to do instead is the following:

// C#:
int i; // No need to initialize for out parameters
setToFortyTwo(out i);

Is there some attribute I can use to instruct VB to mark the
parameter as an out parameter in the generated Assembly?

I had a look through the language reference, but I can't find
anything applicable. But, possibly, there is some trickery with
MarshalAs that could be used? Basically what I need is a way to
tell the VB compiler that "this is *really* an out parameter and
I want you to mark it as such in the assembly."

I'd even consider post-processing the code that is generated by VB
to change the parameter type, assuming that there is some documentation
around that explains how the metadata is stored in an assembly or
an object file. Can someone point me in the right direction for this,
failing an easier solution?

Thanks,

Michi.
 
J

Jon Skeet [C# MVP]

Is there some attribute I can use to instruct VB to mark the
parameter as an out parameter in the generated Assembly?

I *think* that you can use OutAttribute.

Import System.Runtime.InteropServices

and then use <Out> on the parameter declaration.

It seems to work from a quick test, but you'll obviously want to look
at it a bit more carefully.
 
M

Michi Henning

Jon said:
I *think* that you can use OutAttribute.

Import System.Runtime.InteropServices

and then use <Out> on the parameter declaration.

It seems to work from a quick test, but you'll obviously want to look
at it a bit more carefully.

Thanks muchly for that! After much browsing through the doc, I just found
this myself too. Works like a charm:

' VB:
Public Sub setToFortyTwo(<System.Runtime.InteropServices.out()> ByRef i As Integer)
i = 42
End Sub

This does the trick very nicely.

Thanks again for your help, and I apologize for having shouted for help
just that little bit too soon :-|

Cheers,

Michi.
 
J

Jon Skeet [C# MVP]

Michi Henning said:
Thanks muchly for that! After much browsing through the doc, I just found
this myself too. Works like a charm:

' VB:
Public Sub setToFortyTwo(<System.Runtime.InteropServices.out()> ByRef i As Integer)
i = 42
End Sub

This does the trick very nicely.

Excellent. I'd personally use an import and just have the parameter as
Thanks again for your help, and I apologize for having shouted for help
just that little bit too soon :-|

No problem at all - it's not entirely obvious from the docs. It should
really be mentioned clearly in the ByVal vs ByRef documentation.
 
M

Mattias Sjögren

Jon,
It should really be mentioned clearly in the ByVal vs ByRef documentation.

Do you mean in the VB docs? I don't see why VB (or any other language
for that matter) documentation should have to mention C#-isms such as
out parameters. Instead, the C# docs for out should mention that it's
really just a shorthand for [Out] ref.



Mattias
 
M

Michi Henning

Jon Skeet said:
Excellent. I'd personally use an import and just have the parameter as
(<Out> ByRef i as Integer)
but that's a different story :)

Yes, normally, I would do just that. But, in this case, this is code generated
by a compiler, and I have to be careful about name clashes between the
generated code and user-defined symbols, so I can't import an entire
namespace wholesale, for fear of symbol clashes.
No problem at all - it's not entirely obvious from the docs. It should
really be mentioned clearly in the ByVal vs ByRef documentation.

Yes, would be nice, wouldn't it?

Cheers,

Michi.
 
M

Michi Henning

Mattias Sjögren said:
Jon,
It should really be mentioned clearly in the ByVal vs ByRef documentation.

Do you mean in the VB docs? I don't see why VB (or any other language
for that matter) documentation should have to mention C#-isms such as
out parameters. Instead, the C# docs for out should mention that it's
really just a shorthand for [Out] ref.

No, this clearly belongs with VB. For example, VB may need to call into
a DLL written in C# that uses out parameters. To some people, it may
not be obvious how to pass the parameter. Or, alternatively, I may
need to provide a callback function written in VB to a DLL written
in C#. If that callback function uses out parameters, I need to know
how to create an out parameter in VB.

Cheers,

Michi.
 
M

Mattias Sjögren

For example, VB may need to call into
a DLL written in C# that uses out parameters.

They are seen as regular ByRef parameters from VB. The distinction
between out and ref when calling such a method doesn't matter, since
locals are always initialized in VB (so C# definite assignment rules
don't apply).

Or, alternatively, I may
need to provide a callback function written in VB to a DLL written
in C#. If that callback function uses out parameters, I need to know
how to create an out parameter in VB.

Not really. Again, you can just treat it as a regular ByRef.



Mattias
 
J

Jon Skeet [C# MVP]

Mattias Sjögren said:
It should really be mentioned clearly in the ByVal vs ByRef documentation.

Do you mean in the VB docs? I don't see why VB (or any other language
for that matter) documentation should have to mention C#-isms such as
out parameters. Instead, the C# docs for out should mention that it's
really just a shorthand for [Out] ref.

I think it should probably be mentioned in both C# and VB.NET
documentation, to be honest. (And it's not in the C# spec as far as I
can see, unfortunately.)

Given that it's something which can affect more languages than just C#
though, I don't see why it shouldn't be mentioned briefly in the VB.NET
docs though.
 
R

Ravichandran J.V.

I don't see why you should be bothered when you know the usage of the
out parameter in C#, simply use it in a c# class and have the method
called through another method in the same class. This way you will have
the value in an out variable in the C# class. Have the value of the out
variable returned to the VB.Net object.


with regards,


J.V.Ravichandran
- http://www.geocities.com/
jvravichandran
- http://www.411asp.net/func/search?
qry=Ravichandran+J.V.&cob=aspnetpro
- http://www.southasianoutlook.com
- http://www.MSDNAA.Net
- http://www.csharphelp.com
- http://www.poetry.com/Publications/
display.asp?ID=P3966388&BN=999&PN=2
- Or, just search on "J.V.Ravichandran"
at http://www.Google.com
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top