LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

force LabVIEW to find a DLL

Hi John,

 

I came across a few links about using .NET assemblies in LabVIEW that will hopefully be helpful for you:
http://digital.ni.com/public.nsf/allkb/9E1CFF2B47EC4FD386257116005FAB3E?OpenDocument

http://digital.ni.com/public.nsf/allkb/C4EA5ABBEB67AF7C862573F3004D4421

 

As for adding a DLL to the GAC, you can drag the file into C:\Windows\assembly and Windows will automatically take care of registering it with the GAC.  Can you see if adding the original DLLs to the GAC fixes the problem? (Maybe we won’t have to troubleshoot the C0000005 error if the original DLLs work)

 

If that doesn’t work, are you sure that you’re closing all of your references in you’re DLLs?  I’m thinking that the close node in your LabVIEW code is closing the references that LabVIEW is aware of but maybe not closing something that was called in the DLL.  Typically, we recommend creating the DLL as being debuggable, and running the C# debugger at the time of the DLL being called from LabVIEW to better debug what is actually happening in the DLL.

 

I do have a question about when the error occurs. Because you said the error occurs at the close node, does this mean that the DLL successfully ran, performing all the operations it should have performed?

0 Kudos
Message 11 of 16
(1,691 Views)

Thank you for your reply!

 

I don't actually need to add a DLL to the GAC.

 

The crash I'm seeing isn't occuring at the close reference node.  If you were to use Step Into to start my little five-element VI (constructor, invoke [+2 constant arguments], close reference), you could execute Step Into over all three elements, and then eventually get to the point where Step Into isn't available any more.  Then there's only one option left, and that's Step Out.  Stepping Out is where the crash is happening, deep in the bowels of LabVIEW (nothing in the stack trace shows anything related to either of my DLLs).

 

Anyway, I'm still pursuing this.  It looks like it has something to do with the threading that my code in the Win32 DLL is performing, based on the fact that if I don't turn those threads on, the crash doesn't happen.  It's looking like some unintended side-effect or something that I'll hopefully be able to work around.

0 Kudos
Message 12 of 16
(1,678 Views)

One thing that sometimes helps resolve threading problems between .NET or COM objects and LabVIEW is to run the VI that uses those objects in the user interface execution system, which forces them to run in the same thread.  I don't know if that will help here, but it might be worth a try.  The execution system is set in VI properties, under the Execution category.

0 Kudos
Message 13 of 16
(1,673 Views)

Hi Nathan,

 

I gave that a try and LabVIEW crashed again.   Maybe John will get a different result?

 

It was a good suggestion, though - thanks!

 

Diane

0 Kudos
Message 14 of 16
(1,670 Views)

OK, ultimately what I discovered is that my destructor was not being called when I think it ought to be called; as a result, I had threads running which were part of the DLL that was being unloaded -- unsurprisingly, Windows does not like this.  My solution was to provide an explicit "shut down" function to be invoked before the close reference node, to ensure that all of the Win32 DLL's resources, including the threads, would be released/terminated before the destructor unloaded the Win32 DLL.

 

Problem resolved!

 

Thanks, all!

 

=-John-=

 

0 Kudos
Message 15 of 16
(1,653 Views)

You sure have created an involved pattern here. .Net calling a C DLL that returns COM interfaces. The problem with (D)COM is that it is in fact based on OLE and OLE originates from Windows 3.x days, when multithreading was at best a nice wish in Windows. It means that most COM objects were programmed to run from one thread only and when real multithreading got into the picture MS had to bend in hoops and loops to let it keep running.

Unless a COM object is specifically programmed and registered to run as multithreaded object, Windows will attempt to isolate it in its own apartement. This works fairly well if you observe the normal COM rules calling CoInitialize() and friends appropriately, but as component developer in LabVIEW you can't control that as easily since LabVIEW does all this very early on in the UI thread. Calling it again in your component has none or even undesired effects depending on the thread it was called from. If you instantiate non-multithreading objects directly in your DLL you can get weird threading issues, if you use CoCreateInstance() from the same thread that CoInitialize() was called from, you get a nice COM interface pointer, and if you call that function from a different thread you get a marshalled interface pointer. This marshalled interface pointer can also play tricks on Side by Side assembly interfaces as can be seen in this article.

 

All in all I would try to avoid COM whenever possible and certainly not mix it with .Net when everything needs to run in LabVIEW too. It just adds to many hassles to the whole picture, with each of these technologies having it's own very specific ideas about managing resources and thread handling and combining one with the other can be a challenge, although the LabVIEW developer did a pretty good job at that, but combining them all together simply creates so many possible gotchas that are sometimes impossible to avoid all.

Rolf Kalbermatter  My Blog
DEMO, Electronic and Mechanical Support department, room 36.LB00.390
0 Kudos
Message 16 of 16
(1,642 Views)