From 04:00 PM CDT – 08:00 PM CDT (09:00 PM UTC – 01:00 AM UTC) Tuesday, April 16, ni.com will undergo system upgrades that may result in temporary service interruption.

We appreciate your patience as we improve our online experience.

LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Typecast .NET reference in LabVIEW?

We have 2 .NET .dlls, and are trying to use the LabVIEW "Type Cast" function to cast a .NET reference from one of the .dlls to a .NET reference in the other .dll.  Both .NET references are in the same namespace and are compatible (one inherits the other), and the LabVIEW VI "wires up" okay, but the output of the type cast creates an 1172 ("A .NET Exception Occurred") error with the message "Member Not Found" in the 2nd .dll.  This procedure works fine in VB, C++ and .NET.

What are the limitations of the LabVIEW "Type Cast" function?  Is there a workaround other than writing a function in .NET to do the type cast for me?

Joe Gerhardstein
Viasat
Certified LabVIEW Architect
Certified TestStand Developer
Certified Professional Instructor
http://www.viasat.com
0 Kudos
Message 1 of 16
(6,289 Views)
Ah, yes. I'm afraid that the number of options in converting types in LabVIEW can get a bit confusing. However, when it comes to .NET, you need to stick to the "To More Specific" and "To More Generic" in order to cast a .NET refnum to another .NET class. These .NET nodes are designed to use the type checking features in the CLR to determine what is allowed.
Message 2 of 16
(6,284 Views)
Brian:

What we are trying to do is move between two "root" objects that share the same namespace.  For example,

Namespace
    |
    |-- Object 1
    |-- Object 2

Object 1 and Object 2 inherit the properties of Namespace, however starting from Object 1, I cannot create a More Generic object of "Namespace", since it is a namespace, not an object.  In LabVIEW, I would use the Type Cast to move directly between two objects at the same hierarchy level, but this does not work for .NET objects.  Is there a way to move directly between two .NET object references at the same hierarchy level?
Joe Gerhardstein
Viasat
Certified LabVIEW Architect
Certified TestStand Developer
Certified Professional Instructor
http://www.viasat.com
0 Kudos
Message 3 of 16
(6,268 Views)
Oh, I see what you are saying.
 
Unfortunately this is not allowed in .NET. A namespace is really nothing more than a shorthand way of naming an object. Thus the following are exactly the same...
 
namespace A
{
   namespace B
   {
      class C
      {
....
 
and
 
class A.B.C
{
...
 
There is no difference.
 
In .NET, the lowest common denominator of all objects is System.Object. However, what you have are two completely different class structures that have no inheritence relationship other than Object. You could cast a reference to each one down to Object, but you cannot cast across between the two. Thus, if you had 1 and 2 derive from a common base class, you could cast them both to the base class. But in no circumstance can you ever cast betweem two siblings on an class inheritence tree.
 
The careful reader will note that I kept to the term "class" in this discussion. That is because interfaces are completely different beasts. In fact, in .NET terms, you can never inherit from an interface. Instead the term is "implement". So even if one interface derives from another, it is still considered "implementing". The reason I bring this up is that it is possible to cast to completely unrelated interfaces as long as the actual implementation of the object "implements" each interface.
 
Let me know if that didn't make any sense. I may have gone off into more detail than you wanted.
Message 4 of 16
(6,260 Views)
Brian:

We spent a lot of time looking at our .NET code last night, and found a design problem that was only present when doing things the way we were doing them.  Our .NET code had been debugged through a .NET GUI, but not as an API called from LabVIEW.  Will let you know whether this fixes the overall problem.


Joe
Joe Gerhardstein
Viasat
Certified LabVIEW Architect
Certified TestStand Developer
Certified Professional Instructor
http://www.viasat.com
0 Kudos
Message 5 of 16
(6,250 Views)
Turned out to be a bad .NET .dll, so we are running fine.

The LabVIEW "type cast" function works fine for typecasting the .NET references (didn't need to use the "to more specific class" or "to more generic class").


Joe
Joe Gerhardstein
Viasat
Certified LabVIEW Architect
Certified TestStand Developer
Certified Professional Instructor
http://www.viasat.com
0 Kudos
Message 6 of 16
(6,246 Views)
Well, that depends on your definition of fine...
 
Note that the type cast node does not have any error information. All it is doing is taking the type information and changing it. It is kind of like forcing a C pointer to an integer to become a C pointer to a data structure. Maybe it works, maybe it doesn't.
 
The To More Generic doesn't have an error output because we can do compile time checking to ensure it works (we don't do that with type cast...again, think of it like the C pointer cast, it is the user overruling LV opinion on the matter)
 
The To More Specific does have an error output because it is only at runtime that we can test to see whether the instance of type A is really an instance of its child B.
 
So I strongly recommend staying away from type cast unless you are doing some very clever trickery under the covers. The other two will provide safety rails.
 
 
For those with a C background, in summary
 
LV Casting Scheme  ----  C Equivalent
--------------------------------------------------
type cast                           C Cast
To More Generic               static_cast<>
To More Specific               dynamic_cast<>
Message 7 of 16
(6,251 Views)
Well, it's all good and well that I shouldn't be using the "type cast" LabVIEW block, but I cannot use the "to more specific" and "to more generic", as there is no common parent in the hierarchy tree (just a namespace).   I realize that LabVIEW is not going to be able to check my work, but this is the case with any other language as well with this type of type cast.  Since we are doing pointer to pointer (not array to string or something odd), and LabVIEW preserves the value of the pointer, it seems relatively benign.  It's just up to me to make sure the pointers reference compatible data structures.

Are there other underlying issues I should be aware of, or is your biggest concern the lack of "safety rails" (something that I do appreciate with LabVIEW!)?


Joe
Joe Gerhardstein
Viasat
Certified LabVIEW Architect
Certified TestStand Developer
Certified Professional Instructor
http://www.viasat.com
0 Kudos
Message 8 of 16
(6,248 Views)
Welcome to .NET...the rules have changed 🙂
 
As a quick side note - everything derives from System.Object so you can always cast to that...but it isn't really relavent to you here.
 
It looks like the fundamental confusion is the difference between languages such as C/C++ and managed (.NET) lanaguages. In C/C++, it is perfectly legal to cast a pointer between two different types as long as, as you say, you ensure the data layout is the same. The reason you can get away with this is that C/C++ has no actual knowledge of what a given memory pointer is. It is just an address. You tell it that it points to struct XYZ then okedokey.
 
However, all "pointers" (references) to objects in .NET have what is known as metadata associated with them. Metadata is a complete definition of what the type is that you are pointing to. If you try to convert a reference between two classes that aren't in the same inheritence line, then .NET throws an exception. In addition, unlike a normal C/C++ compiler, .NET says nothing about how the memory for the class is going to be layed out (advanced users - yes, there is an exception, but almost everyone uses auto layout).
 
The confusion is probably helped along by the fact that managed C++, which is what the LV/.NET interop is written in, is considered an unsafe language in .NET. This is because you can, like Type Cast, bypass some of .NET's security systems. If your VI is working, it is only because we are bypassing the metadata check and that you are lucky. I'd be willing to bet that you are going to have a fatal crash at some point (.NET 2.0, service pack update, change in the compiler, etc).
 
So basically the approach you are taking with your class hierarchy isn't a valid one for .NET, even if you have gotten it working right now. I'd be happy to go into more detail or brainstorm with you either on this thread or directly by email (bloggingbrian@gmail.com). There is probably a .NET approved way of doing what you are trying to do. I'd be happy to help you find it.
Message 9 of 16
(6,243 Views)
Trust me, this isn't the first time that casting in LabVIEW has caused confusion. To try to help with that, I've written up a posting on my blog about the various ways of casting in LV for .NET.
 
Message 10 of 16
(6,236 Views)