Stagg54 Posted March 8, 2012 Report Share Posted March 8, 2012 I'm just curious how many use libraries in your day to day development (I'm assuming a fair amount of you do). I'd like to know how and why you use them, especially if you are using multiple libraries in the same project. I'm running into this problem and I'm not sure its inherant in using libraries or if I'm just misusing them or not using them as intended. I have this project and every major component is in its own library. I have a config library. I have a notification library. I have a synchornization library. I have a file writing library. I have a TCP/IP communication library etc. However what I find is when I want work on one small component it ends up loading almost every library in the project. For example in my notification library, if I load any vi in that library it loads the whole notification library. There is a vi somewhere in the notification library that sends out a TCP/IP message. Because it uses a vi in the TCP/IP communication library to get a queue ref, now it loads the TCP/IP library. And also somewhere in the notification library it writes something to a file, so it loads the file library which happens so use a semaphore to control access to the file which loads the synchronization library, which somewhere has config file entry which determines the size of some queue which no requires loading the configuration library. And it goes on and on. So now to edit a single low-level vi I end up loading multiple libraries into LabVIEW. Anyone else run into this problem? How do you handle it? How do you determine what to put in libraries and what not to? This problem gets even worse, because I have 2 applications. One is an HMI app running on Windows and the other is an RT app. For communication I send objects over TCP/IP and have a command pattern that runs on the recieving end. When I do that however then I up loading half the HMI app into memory on the RT target, just because one of the messages references a library on the HMI. Now I have all this code loaded in RT that is intended for the HMI and will never run in the RT app. Did I explain my problem well enough? thoughts? Quote Link to comment
jgcode Posted March 8, 2012 Report Share Posted March 8, 2012 Did I explain my problem well enough? I like to use libraries when appropriate. In the first part of your question (not RT issues) - yes .lvlib file will be loaded along with the called VI(s) but can you go into detail about what problems this is causing you? Quote Link to comment
Popular Post Daklu Posted March 9, 2012 Popular Post Report Share Posted March 9, 2012 I'm running into this problem and I'm not sure its inherant in using libraries or if I'm just misusing them or not using them as intended. No, you are not misusing libraries as far as I can tell and the "problem" you are seeing is one of the reasons I use them. In short, you have discovered an error in your design. When building an application you have to be aware of the dependencies you are creating between components. Currently your low level components are statically dependent on higher level components. Sometimes that is useful (such as when implementing a HAL or plug-in frameworks) but a reasonable rule of thumb to start with is, "let high level components depend on low level components, but not the oher way around." Grab a piece of paper and draw a rectangle for each component in your app. Next draw arrows from each component to every other component that it statically depends on. This is your dependency map. Do you see any cycles? (My guess is you'll find several.) You'll want to change your code to break those cycles. That's why you aren't able to load a single library without loading the whole application. 3 Quote Link to comment
Stagg54 Posted March 9, 2012 Author Report Share Posted March 9, 2012 No, you are not misusing libraries as far as I can tell and the "problem" you are seeing is one of the reasons I use them. In short, you have discovered an error in your design. That was what I was thinking. I guess I'll have to look a little closer at my design. to jgcode: It's not really causing problems so much as it seems odd to me that to load and work on a low-level component I have to load essentially the whole project. I think goes back to what Daklu said about dependencies. I think I need to readjust my paradigm to "let high level components depend on low level components, but not the oher way around." Quote Link to comment
Daklu Posted March 9, 2012 Report Share Posted March 9, 2012 (edited) Dependency management has not been discussed much on LAVA or in any of the NI material I've seen. Understanding its importance was one of those "Aha!" moments for me. Now creating a component dependency map is one of the very first architectural tasks I do, both on new projects and when taking over an existing code base. The VI Hierarchy window has the ability to collapse a library down to a single icon. That can be very useful for figuring out your dependencies in an existing project. I don't have an easy "one size fits all" fix for breaking dependency cycles. The best solution depends on many project-specific considerations. However, here is an (incomplete) list of general guidelines... 1. Avoid dependency cycles. (I know I said it before, but IMO it ranks pretty high on the "rules not to break" list.) 2. Reuse components should *never* depend on application-specific components. Ideally reusable components have no other dependencies, though occasionally it may depend on another reusable component. 3. The dependency map doesn't need to be a tree. In other words, it's okay for 2 or more higher level components to depend on the same low level component. 4. Custom data types, such as classes and typedefs, tend to create lots of dependency links as the data is passed around the application. Off the top of my head here are three ways to work around that: 4a. Create a low-level, app-specific library for your custom data types and have all your non-reuse components depend on that. 4b. Use Labview's native data types to exchange information. A 2d string array makes a great lookup table for passing arbitrary information. (Note: Often using native types to exchange information increases the opportunities for runtime errors. It takes diligence to ensure you are adequately testing those possibilities.) 4c. Use "adapters" to convert from one data type to another. This can be especially useful when your reuse component communicates in generic or custom data types and you want to use a different, application specific data type. [Note: In this thread, when I use the word "dependency," I am referring only to static, or compile-time, dependencies. Other types of dependencies include dynamic dependencies (depending on a dynamically loaded vi via path information) and definition dependencies (depending on a schema, protocol, or other definition not explicitly defined by code.) Managing those dependencies is important but beyond the scope of what I am discussing here.] --------------------- [Edit - It will be well worth your time to learn about dependency injection. Don't know how I managed to forget mentioning that...] Edited March 9, 2012 by Daklu 1 Quote Link to comment
GregR Posted March 9, 2012 Report Share Posted March 9, 2012 In 2011 (not sure about 2010) the VI hierarchy window can help draw your dependency map for you. There is a "Group Libraries" button that will put all VIs in a library together. Cycles between your libraries then show up as backwards dashed references. You can even collapse each library to a single item. This does mean you have to load all your VIs into memory to get the full graph, but it works. I wanted this feature way back when we introduced libraries but it took a while to get it. 1 Quote Link to comment
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.