Just had an interesting support issue and I ended up learning some new syntax in C++/CLI, so I thought I'd share it with you. This has to do with passing values by reference and how they map within LabVIEW.
So, here is the question - you want to create a method in .NET that passes an integer by reference, and have that map correctly within LabVIEW.
Wow - this turned out to be a longer post than I thought - I was very verbose on this one...I tried to put some headings in case you want to skip to the section you're interested in...
Definitions
Some definitions for those that don't know. When .NET first came out (versions 1.0 and 1.1), the C++ team created extensions to the language to allow you to write .NET code in C++. This was known as managed C++. It wasn't very pretty, but they were trying to stay close to the C++ language design.
Because C++ remained a very popular language for .NET, the team decided to redo the synatx in .NET 2.0 (VS.NET 2005). This new syntax is called C++/CLI, and it's pretty much agreed that this is a far superior synatx for programming .NET.
Examples in .NET 1.1
In C#, it would look like this
public void DoubleTheInteger(ref int x)
{
x *= 2;
}
Okay, so let's look at managed C++ first. Can you tell the difference between these three methods?
public __gc class TestClass
{
public:
void DoubleTheInteger(int& iValue);
void DoubleTheInteger(int* iValue);
void DoubleTheInteger(int __gc* iValue);
};
void TestClass::DoubleTheInteger(int& iValue)
{
iValue *= 2;
}
void TestClass::DoubleTheInteger(int* iValue)
{
*iValue *= 2;
}
void TestClass::DoubleTheInteger(int __gc* iValue)
{
*iValue *= 2;
}
Believe it or not, these are radically different. The first example, which uses standard C++ syntax for passing by reference (that's what we want, right?), gives us the following actual definition in .NET
.method public instance void DoubleTheInteger(int32* modopt([Microsoft.VisualC]Microsoft.VisualC.IsCXXReferenceModifier) iValue) cil managed
This is the MSIL syntax, but the underlined part is the key - an int32 pointer! Turns out that .NET doesn't support C++ references. So instead it's mapped to a pointer (which is what it really is anyway, even in C++) and a special bit-o-magic-text is added to tell VC++ that's it is meant as a reference.
If you look at the second method, it's very similar
.method public instance void DoubleTheInteger(int32* iValue) cil managed
So, just the same as the first, but without the extra modopt decoration.
The point is (finally, eh?) that writing "what you would expect C++ syntax" gives you a .NET pointer (aka managed pointer), and this results in a .NET refnum in LabVIEW!!! Thus you won't see a nice mapping to a LabVIEW integer. You get
ick... So, let's look at the last one - what is that? This uses the managed C++ tag of __gc to decorate the pointer and say that it's really a .NET reference, not a C++ pointer. Now this is mapped to the same .NET type as the C# example...
.method public instance void DoubleTheInteger(int32& iValue) cil managed
Don't get confused by the & symbol - it's just MSIL's way of saying a .NET reference - it's not a C++ reference. Now, in LabVIEW, you get
And the world is a happy place once more.
Examples in .NET 2.0
As I mentioned before, managed C++ has given way to C++/CLI in .NET 2.0 and VS.NET 2005. So the __gc has given way to the carrot (^) as the syntax for a managed reference. Given that, let's try converting our example to
public ref class TestClass
{
public:
TestClass() {}
void DoubleTheInteger(int^ iValue)
{
*iValue += 2;
}
};
Quite a change, eh? But notice how you can write everything in one spot, just like in C#...much nicer. Okay, back to the issue at hand - does this give us what we want? NO! Surprise! Here is what the MSIL looks like for this one
To translate, the syntax was being precise - this is a .NET object reference - thus the integer must be boxed up into an object and then that is being passed. This gets into some confusing parts of value-type versus reference-type and boxing, so we'll just say, this isn't what we want.
The solution is to use interior pointer syntax. Interior pointers are another advanced concept that I'm not going to go into right now. Suffice it to say that they have a nice alternate use - passing primitives by reference!
public ref class TestClass
{
public:
TestClass() {}
void PassPointerByRef(interior_ptr<int> iValue)
{
*iValue *= 2;
}
};
Now you get the nice auto-mapping of the integer type within LabVIEW and evil has been defeated. Congratulations!
Hi, Your post is very helpful. But I still need to dig into "interior_ptr" to know why it can fix my code problem, :-) Thanks,
Posted by: Bruce Li | May 15, 2008 at 06:39 PM
To understand about the pointer in well concept is really imoprtant because pointers can change the value at memory location and give unpredictable errors and we try to find the problem in code which is useless so using pointer in wise manner is really important
Posted by: asp.net programmer for hire | September 17, 2010 at 06:40 AM
very nice,i like it very much.It is a harvest journey for me when after have a careful look of your blog.Thank you for constantly posting of so many useful tips.They are such a great help to me.Thank you very much!
Posted by: supra tk society | October 28, 2010 at 04:13 AM
Thanks for the sharing of those photos and painting works! I wonder whether you are thinking about posting a manual of HDRI? That will be helpful.
Posted by: jordan 2 | November 01, 2010 at 03:45 AM
Yes. Look! Improves your ability to create nice looking objects and graphics.We have a nice picture.What a nice little book!In fact, they are very nice souvenirs.It would be nice to have less homework.
Posted by: UGG Bailey Button On sale | November 02, 2010 at 02:03 AM
Hallo I am homeā¦it feels really good
Posted by: Air Jordan Shoes | November 03, 2010 at 01:55 AM
that's quite humorous , could not help laughing, booing a bunch of small fry are all laughing along. Fan Shaocheng not said a word all the other finished laughing, and if the former might fear
Posted by: Oakley Sunglasses Sale | July 02, 2011 at 02:30 AM
A good blog always comes-up with new and exciting information and while reading I have feel that this blog is really have all those quality that qualify a blog to be a good one.
Posted by: Polo Outlet Online | August 12, 2011 at 03:21 AM