Jump to content

Leaderboard

Popular Content

Showing content with the highest reputation on 02/15/2011 in all areas

  1. Because some people like to think of NI as the Sith Lords of the Empire constantly oppressing the LV users, while the LAVA jedi fight for freedom and openness. It's a bad comparison... after all, you couldn't pay Emporer Palpatine enough to treat you well. NI, on the other hand, has a well defined price list for good treatment. :-)(And now I need to get back to testing the driver software for this new Purple Lightening Generator that NI will be releasing soon. I wonder what we plan to use this for and why we seem to go through beta testers so quickly...) The packed library should be a good way to create a plugin, but you have to play by the rules. (I say "should be" -- I haven't done it myself, but I've heard testimony from others.) 1. A packed library absorbs all the subVIs and other dependencies needed to support its public VIs except 2. VIs and dependencies owned by other packed libraries. That means that you need to make your root class be a packed library so that when you make a single plug-in into a packed library, it doesn't absorb the parent class. Instead, it uses the parent class in the packed library. Then you write your entire framework in terms of that parent class in the packed library. To put it another way: 1. Write Parent.lvlib:Parent.lvclass 2. Build packed library of Parent.lvlibp:Parent.lvclass. 3. Write framework using Parent.lvlibp:Parent.lvclass 4. Write Child.lvlib:Child.lvclass. 5. Build Child.lvlibp:Child.lvclass. Any other class that is going to be used by both your Parent class and your child classes needs to be inside that Parent.lvlibp.
    2 points
  2. Hey John, are planning on starting a new project or doing a running refactor on your current code? My sense is that a running refactor is technically more challenging but is less risky overall as it offers continuous incremental improvements on existing production code instead of a starting a new dev effort on an incompatible parallel branch. My thoughts and experiences, for what it's worth... Things to avoid 1. Don't try to do a detailed design before you start coding. I have yet to produce a design on paper that didn't need to be altered--sometimes significantly--when implemented. I discovered I spent wasted a lot of time working out details on paper that never got implemented because of a change somewhere else. 2. Don't get bogged down in process. The goal is to develop good software, not develop good processes. Too much process is just as bad as no process. Finding the sweet spot for your group will take some time. 3. Don't be overeager to use inheritance. It is actually a fairly restrictive relationship. Delegating tasks via object composition is a much better general purpose way to reuse code and give an object additional abilities. Things to do 1. Find a development methodology that works for you. There are lots of competing ideas about the "right" way to develop software: Test Driven Development, Agile, Waterfall, Unified Process, etc. In truth, the "right" way is the way that helps you deliver the product on time. There is no single best methodology. It depends a lot on the corporate culture, types of projects being developed, requirement maleability, timeline, etc. I've taken bits and pieces from several methodologies and combined them into an informal process that works well for me in my current environment. Your process will likely be different. 2. Architect from the top down; design and implement from the bottom up. (This point is debatable--every dev has their favorite way to do things.) When I'm architecting the app I break the requirements into functional components and figure out the api for each of those components. Each component then get broken into sub components if the complexity warrants it. At this time I'm just thinking about the component's public interface; I don't worry about implementation details. When I get to the point where I have components with a manageable size then I start implementing code, assembling the components into larger components as I work my way back up the architecture. 3. Decouple the UI. You mentioned using a web front end. It's possible (and not terribly difficult) to decouple your UI from your functional code in a regular Labview app. I get irritated with programs where a simple UI change propogates down into the lower levels of functional code. That's just poor (IMO) design. Plus, decoupling the UI makes it possible to create unit tests at the application level. 4. Dedicate time for refactoring and simplifying your code. Software development is a very organic process. (At least for me.) When I get to a point where a component's public interface works the way it is supposed to, it's not really done. I can pretty much guarantee the internal workings have some extra fat laying around. Take time to do some lipsuction--it'll improve the long term maintainability of your app. Addressing some of the specific items you raised... Design Patterns - One of the best bits of advice I read about design patterns is to "apply design patterns gently." In other words, don't carry around your design pattern solution looking for a problem to solve. Applying them where they are not needed adds a lot of unnecessary complexity. (It's a great way to learn the design pattern, but I have a lot of extra stuff in many of my early applications.) Unit Testing - Contrary to common perception, unit testing is not free. In fact, it is quite expensive. Not only does it take time for initial development, but you have to go in and fix the unit tests when a design change breaks them. When a test run results in a bunch of failure, chances are at least some of those failures are due to errors in your test cases. Every minute you spend fixing your test cases so they result in a pass is a minute you're not spending improving your code. Don't get me wrong; I think unit testing can be extremely helpful and I'm still trying to figure out how to best use it as part of my dev process. But I think it's a mistake to try and create a comprehensive unit test suite. Packed Project Libraries - Some users have reported problems with ppls. You might want to wait a year or two before including them as an integral part of a mission critical app. -Dave
    1 point
  3. I'm still waiting for the 2009 SP2 Go Paul.
    1 point
  4. Hmm... suppose your UI has a "Start" button. You're not using LVx to trigger a start by referencing the front panel control are you?
    1 point
  5. I've found the best mentors as those you work beside - there's something to be said for working with people that are better than you: you're always challenged, and it's the best way to improve. So, looking for a mentor is a good idea, but looking for a company that is full of mentors is even better!
    1 point
  6. The InstanceDataPtr is basically what the GetDSStorage() and SetDSStorage() functions provided for CINs. It is a pointer value LabVIEW maintains for each Call Library Node in a diagram and in the cases of reentrant VIs with Call Library Nodes for each instance of such a Call Library Node. Your DLL can specifiy the three Callback functions ( I still think the name callback function is a mistake for this functionality) that all accept a reference to this InstanceDataPtr. These three functions Reserve(), Unreserve(), Abort() correspond somewhat to the CIN functions CINInit(), CINDispose(),, and CINAbort(). Usually you would in Reserve() check if the InstanceDataPtr is NULL and create it then or reuse the non-null value. In Unreserve() you should deallocate any resources that you created for this InstanceDataPtr. In Abort() you could for instance cancel any pending IO or other operations associated with this InstanceDataPtr to prevent the threaded Resetting.... dialog when your DLL function hangs on a IO driver call. The actual function associated with the Call Library Node can be configured to have an extra InstanceDataPtr parameter that will be not visible as terminal on the diagram. LabVIEW will pass the data pointer instance stored for the current CLN instance to this parameter. Please note, this is strictly for managing a specific CLN instance. It is not meant to pass around as a token between different CLNs or even different instances of the same CLN in case that the CLN resides in a multiple instantiated reentrant VI. It seems what you want is more a kind of token or handle you can pass between different CLNs to identify some resource. This has to be done by your library for instance by creating a pointer where all the necessary information is stored. You can treat this as opaque value as far as LabVIEW is concerned. Basically you configure the according parameter to be a pointer sized integer and pass this "handle" around in LabVIEW like this between the different CLNs. If you need to access content inside this handle in a LabVIEW diagram your library should export corresponding accessor functions that you can import with CLNs.
    1 point
  7. Confirmed. I'll leave it a week or two so to see if anything else crops up then release a bug fix.
    1 point
×
×
  • Create New...

Important Information

By using this site, you agree to our Terms of Use.