06-25-2017 03:25 PM
And just as a follow up, I (think I successfully) implemented explicit linking in my test application, and the first loop runs fine, but then the second loops still crashes the MATLAB runtime, even with FreeLibrary() called prior to the next LoadLibrary(). Thanks again for the ideas on how to tackle this. Learn something new every day.
06-25-2017 03:29 PM - edited 06-25-2017 03:30 PM
But why do you have to call the Matlib initialize and terminate functions before and after each execution? Does the Matlib library otherwise produce bad results?
I would think that it is enough to call initialize() once before executing any function, then execute as many functions and as often as you like, and only when your LabVIEW app wants to close, call the terminate() function in order to clean up everything.
At least that sounds like the correct thing to do. Maybe the Matlab libraries implement some weird resource management that requires something else, but that would be not just weird but pretty stupid.
06-25-2017 03:36 PM
The root of the issue is that when calling DLLs that use the MATLAB runtime, you cannot re-initialize the runtime after it has been terminated without, it seems, fully releasing all DLL associated resources. However, ending a Labview VI, doesn't fully release those resources and the result is that I cannot rerun the VI of interest without it crashing, unless I fully close Labview and restart it each time.
Initializing at the beginning and terminating at the end is indeed what I would do, if only for the reason that the loading and unloading adds incredibly overhead to the call (the COM and .NET implementations are the same way). The only difference is that the DLL approach needs to be fully unloaded from memory between runs to avoid the crash.
My solution right now is simply to use the COM library instead, which is actually a bit easier now, since the COM methods take variants in, and as such are polymorphic in the sense that I don't need one VI wrapper for handling arrays, and another for scalars.
06-27-2017 01:50 PM - edited 06-27-2017 01:51 PM
You actually are able to unload a dllfrom LabVIEW programmatically but it has some disadvantages. Namely, in order to do this you have to enable the "Specify DLL path on Block Diagram" option of the dll call. Which makes each of these calls a bit slower because they have to load the correct instance of that dll at run-time. It is a small overhead, but if you are trying to do anything at high speeds, or deterministically, it will probably be enough to affect you.
I have used this method in a Windows based implementation, that saw the exact same issues with a Simulink(Matlab) dll as you are seeing. It basically boils down to every reference to the dll call, needs to have a path wired in, and when you want to unload the dll, you need to call every one of them with an empty path. Once all references are called with an empty path, the dll gets unloaded. Here's an NI page describing it: http://digital.ni.com/public.nsf/allkb/77594203D78D12278625729100758BE5
To answer some other questions, this shouldn't be required if the dll was built properly, that's correct. It's initialize function dynamically creates some variables, which then don't get cleaned up via the terminate function, but it also initializes all the state variables. There are ways around this, but it requires someone that has enough knowledge to manipulate the c-code that is generated (or the makefiles) from the simulink model before it is compiled into a dll from simulink. This could be done by either manipulating the terminate call to clean up the correct memory, or creating a separate "Re-Initialize" function that just resets all variables to initial values.
I went down the road of manipulating the c-code once, and I got it to work, but these compilations can change with every version of Simulink/Matlab. I was not the person in charge of these models, nor is this my area of expertise, so it became a pain for me to manage.
Anyway, let me know if that works for you, or if you have more questions.
06-27-2017 01:57 PM
Thank you for the feedback. I took at look at the link you shared, and that is a strange behavior indeed...some heavy overloading of the Call Library node...
In any case, my discussion with Mathworks somewhat sealed the deal as far as the C DLL not being viable for use in LabVIEW without some tricks like you mentioned. I doubt I will take the time to try it myself. Instead, I'm investing more in my use of the Mathscript node and custom scripts/functions to get done what I need.