07-11-2018 08:49 PM
In "Project1" I created a lvlib that has a class that uses a .NET assembly (the class's private data contains a .NET object from the assembly).
Everything works just fine when I use the lvlib in a VI as normal LabVIEW source code.
When I build the lvlib into a packed library it places the .NET assembly with the .lvlibp file. This seems normal.
However, when I load the packed library into a "Project2", it has a warning that it expected the .NET assembly to be at one place but found it at another. The new location is the one located with the lvlibp file and the old location is the absolute path to the assembly in Project1. However, when you look at dependencies, it shows the assembly twice (one for each of the previously mentioned paths).
Also, at a random time after adding the lvlibp to the Project2 OR when I execute a VI with code from the lvlibp, whichever comes first, there is are a couple popups. The first one says "Cannot load Diagram of "MyLib.lvlibp:MyClass.lvclass:MyClass.ctl" where the only button says "Cancel Save". After clicking on the button, I get "LabVIEW: Cannot load block diagram. Cannot save control "MyLib.lvlibp:MyClass.lvclass:MyClass.ctl" with an OK button.
After clicking OK, I'm able to run my VI like normal and it works properly.
Trying to build this VI into an executable fails and stalls LabVIEW to the point I have to manually kill the LabVIEW.exe process via Task Manager.
LabVIEW 2017 SP1
Solved! Go to Solution.
07-12-2018 02:19 AM
I think the root of these problems is that LabVIEW loads .net assemblies globally. Not sure why it would show two dependencies, that could be a bug...
I experience similar problems when replacing an assembly with a new one (LabVIEW needs to be closed for that to work, or at least I close it to avoid problems).
AFAIC, Bottom line is you can't have two projects referring to the same assembly with different paths without confusing LabVIEW...
07-16-2018 12:25 PM
So, it looks like the issue is actually coming from having a .NET object reference in the private data of the class inside the packed library. I think it is causing it to use an absolute path (which it should never do according to one article on ni.com). So, most references update to the proper one while the one in the class inside the packed library doesn't properly use the one that is loaded into memory. This is it shows two identical .NET assemblies in the dependencies.
Is this a bug in LabVIEW? Maybe, it certainly looks like that might be the case.
07-17-2018 03:06 AM
@NathanJD wrote:
So, it looks like the issue is actually coming from having a .NET object reference in the private data of the class inside the packed library. I think it is causing it to use an absolute path (which it should never do according to one article on ni.com). So, most references update to the proper one while the one in the class inside the packed library doesn't properly use the one that is loaded into memory. This is it shows two identical .NET assemblies in the dependencies.
Is this a bug in LabVIEW? Maybe, it certainly looks like that might be the case.
Yes, this is a known problem. There's been some talk about it in a private forum, but in a slightly different context of moving projects from one system to another.
A known solution is to put a parent .NET class (system.object or something) in the private date, and make an accessor VI that returns the casted class.
07-17-2018 01:58 PM
Thanks for the information and potential fix.
I was able to get it working by not using any reference wires at all (the .NET object must be implemented as some sort of singleton inside of the assembly because it seems to work without passing around the original reference). Since this is an abstraction layer and I never intend instantiate the object more than once so it should work for my particular use case.
07-18-2018 02:31 AM
@NathanJD wrote:
(the .NET object must be implemented as some sort of singleton inside of the assembly because it seems to work without passing around the original reference).
Objects that always return the same reference are usually marked with an S at the start, for Static. These could be considered global objects as well, and those would indeed act as singleton.
For a user, Static, Global or Singleton doesn't make that much of a difference. I've only seen them referred to as Static. I think a global or singleton object would still return different references when obtained in some way. Those references are used for reference counting. For instance closing a reference means closing one reference to the object, not closing the object itself. The object can be released when the count is 0...
07-18-2018 10:13 AM - edited 07-18-2018 10:40 AM
I'm not familiar with .NET programming so I'm not really sure. If it is what you say, maybe we have a memory leak that hasn't yet been noticeable. It's certainly something to think about if we see strange crashes.
07-19-2018 03:04 AM
If you put a probe on the wire, and it returns a different number each iteration, it needs to be closed. I think in general it's as simple as that.
07-19-2018 10:01 AM
If I use the constructor more than once I get do get different refnums. But, when I call methods using an invoke node without any refnum input, it always returns zero and the method actually does what it is supposed to do. Also, the methods do have a [S] in front of them.
07-20-2018 09:55 AM
I'd say don't use a constructor, and assume the [S] means static, and don't worry about closing it. Guess you'd figured the same?