In one of my recent projects I had to call a custom made .NET Assembly in LabVIEW which provides several events to register for. As .NET support is generally available (within known limitations), there is but one unknown "feature" that caused big trouble to me and everybody who might want to do something similar:
#please notice that whenever I now talk about anything in .NET, I see the things from the view of C#
Let me give an example code in C# to demonstrate the implementation for use in LabVIEW:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Text
namespace SUPERSPECIALPROJECT
{
// delegates
public delegate void myDelegate( object sender, myEventArgs e );
// the event args (plain example)
public class myEventArgs : EventArgs
{
// some member variable
private string m_strMessage;
// the constructor
myEventArgs(){}
// a public property
public string Message
{
get{ return m_strMessage; }
set{ m_strMessage = value; }
}
}
// the public object I want to use in LabVIEW
public class myLVObject
{
// create the event for registration in LabVIEW
public event onMessageChanged myDelegate;
/*
* I don't want to write any more here, but basically the event above is
* fired whenever my asynchronous process feels like it.
*/
}
}
Okay, so now I...
- Build the .NET assembly
- Create an instance of myLVObject in LabVIEW
- Wire the class wire to the Register Event Callback and select the 'onMessageChanged' event.
- Create the callback VI and access the data of 'myEventArgs' within the property 'e', no problems.
So far so good.
However, even though my .NET object runs fine in C# (Yes, I tested it in C# first), LabVIEW does never ever run the callback VI. The reasons were hard to find and I actually had to call NI directly for this. We did some tests and I finally got a confirmation on my assumptions:
1) The asynchronous process does correctly fire the event, but for some reason the developer does not send any 'sender' (the object is just NULL). -> LabVIEW will not execute the callback VI
2) The asynchronous process does correctly fire the event, but for some reason a value of my implementation for 'eventArgs' is NULL (let's say the parameter 'm_strMessage' is NULL). -> LabVIEW will not execute the callback VI
As I have no access to the asynchronous process and have no chance that it will ever be updated for me, I wrote a wrapper that provides my own set of events that replace all null-values by empty values. (like m_strMessage will be "" instead of NULL) -> Finally LabVIEW will accept the love of my events
This behavior is confirmed by NI. The actual event is somehow compared to the callback VI, which will only be executed if the types match. NULL- Variables are not recognized and to LabVIEW it seems as a completely different data type. This will not be changed for future versions unless I get it through the Idea Exchange
The most annoying thing is, if there is any NULL variable somewhere within the scope of either sender or e, the event will fail executing in LabVIEW and LabVIEW only. I know NULL is not a very good practice, but there is no way to replace NULL if you don't have access to the sources (as in my case). The current solution by using a wrapper does work, but takes much time to implement and it has to be maintained.
Finally for anybody who kept reading so far:
I don't see any reason why this behavior could not be changed (LabVIEW does currently just do nothing) and therefore suggest two enhancements:
1) Allow NULL-Variables (auto-replace with empty variables) <-- might be a hard challenge
2) Warn me whenever a callback VI does not match the type of the connected event, as it is currently almost impossible to track properly.
The latter one might be the easiest to implement and would already cover issues with 1) partially. Anyways, we definitely need a better way to catch such issues in the future.
Discussion is open now
You must be a registered user to add a comment. If you've already registered, sign in. Otherwise, register and sign in.