-
Posts
3,183 -
Joined
-
Last visited
-
Days Won
204
Content Type
Profiles
Forums
Downloads
Gallery
Posts posted by Aristos Queue
-
-
The Endevo UML tool integrates fully with LabVIEW, does do code generation and code extraction (generate the UML from a VI hierarchy), and is the recommended tool by National Instruments for G developers who need UML support.
-
Already did...Would you share the answer now? I understand what's been discussed but haven't learned if I should learn to use Singletons. -
For those who don't know, hovering your mouse over an XKCD comic provides a tip strip that is additional humor or commentary. In this case the tip strip says, "Pool on the leak must've sprung a leak." ;-)
-
Post a copy of the VI you've got so far -- some folks here might be able to recognize your bug just by glancing at your diagram.
-
Hello,
I have been using LabVIEW for nearly 10 years but I have to admit I am a little stuck.
I have to use several VC++ DLLs from LabVIEW 2009.
I have no choice than using those DLLs as the code is very large and there is no time to revert back to LabVIEW only.
I have found a good article about calling C++ using a C wrapper at http://labviewwiki.o.../shared_library
I was wondering if someone had done something where instead of calling a double it would be an object.
Any help would be welcome.
Many Thanks,
Christophe
The only DLL calls I've had to make to C++ all involved a C interface where I just needed to pass the pointer to the class (which LV can easily hold onto in a uInt32 or a uInt64 as long as LV isn't expected to access the data of the object directly). I'm sure there is a solution if the interface is actually a C++ exported function, but I don't know what it is. This may be a question better posted on NI.com/forums pages. The AEs there get questions about DLL calls all the time and may have a ready answer for you. No promises, but I'd suggest trying it.
-
Can you Stephen please update the document to contain reasons why DVR terminals do not support dynamic dispatching?
I never did get around to updating the white paper, but I typed this up today:
-
- Popular Post
- Popular Post
If you dynamically registered for an event that you had never included in your code, there would be no frame of the event structure that would handle that event. The Event Structure has to have a frame for handling an event of type XYZ. You can change which particular event of type XYZ you're registered for (one coming from VI X or one coming from VI Y or a different user event of the same type) but you have to have a frame to handle whatever that event happens to be.I've often wondered why I haven't been able to add or remove user events that are registered to an event structure. If the Register for Events prim behaves similarly to the Bundle (not Bundle by Name) prim, then that explains a lot. I still wish there were a built-in way to filter user events at runtime, but at least I have (I think) a better understanding of the current behavior.To register for a truly new event, one that isn't in the event structure, you'd need to supply not only an event refnum but also a VI refnum of the VI to be invoked when the event is fired. That VI would need to have 1+M inputs and 1+N outputs, where M is the tunnels on the border of the Event Structure plus one for the cluster of the event data itself (the node on the border of the event structure) and where N is the number of output tunnels from the Event Structure plus one for the output cluster of the event (the dispose? output if it exists... I'm not sure if there's any other event outputs).
Thinking about this also made it clear to me why we cannot ever support polymorphism of the user event wires. It is the wires themselves that propagate the types to the Event Structure. Those types have to be known at *compile* time. If you upcast all the wires, it would be no different than if you had created all your events with LabVIEW Object in the first place: you'd loose all the type safety in the Event Structure, and all the events would be named the same.
Now, consider this:
What's the solution? (When reading this picture, pretend that Graphics.lvclass is named something like "Event.lvclass" and "Point.lvclass" is a derived class of "My Specific Event.lvclass"... doing that pretending will make it easier, I suspect, to get the idea.)
- 3
-
These are the only ideas I can think of...
a) Try upcasting your objects to LabVIEW Object. That loses your type safety but it might be acceptable in some cases.
b) You can wrap them in a variant and carry around an array of variants
c) The Event Registration node creates a composite event registration wire out of multiple events. Can you use that? (It's more like bundling with a cluster than building an array, so probably not much use to you.)
For the record, no one has ever asked for this before and I've never thought to try this. Anyone see a reason why the polymorphism couldn't be added?
- 1
-
-
Yeah... I've got a whole set of specs for this, including VIs that would define the class's behavior when wired to the ? terminal of a case structure, defining coercion dots for classes to non-class types, etc. I wanted those back in 8.2, but other things keep getting in the way. There is some limited work being done in this area today that you should see either 2010 or 2011.Just a thought... but could there be any possiblility to allow "special VIs" for classes kind of like "Ability" VIs for XControls. That way, a developer could specify how a class should behave when it gets serialized, etc?
-
JAVA has a built-in serialization mechanism that can be privitized if desired. C# has a built-in "to string" but not a "from string". C++ does not have a built-in to or from string. I find that the C# system is the most common among other languages.How do other OO languages handle persisting objects to disk?
No. That would defeat the entire purpose. It has to be a class-level decision, in the hands of whoever is deciding how much security this particular class needs to have.Just out of curiosity, was there ever consideration given to the primitive having a context-menu option to offer access to either behavior?
-
- Popular Post
- Popular Post
You need to have one of those fields at every level of inheritance -- if the child segment is non-default but the parent segment is the same as default, only the child segment will be written down.The work around I used (which while not the "nicest" approach, worked quite well) was to have a field in my class that I would always change. In the case that I'm thinking of right now it was the filename - unnecessary, for the most part, but did come with the benefit of allowing for a "save" versus "save as" type of functionality.
Before the smiting begins, let me lay out "how we got to why things work the way they work today".
A) In LV 8.2, the first OO version, there was no XML support for objects. The only built-in persistence for objects was the Flatten To String primitive.
B) When we save a VI, we save the value of diagram constants and default values for controls. To save space, we don't bother to write down those values when they are the default default value of the data type.
C) LabVIEW classes are the first and only data types in LabVIEW where the default default value of the type can be changed. You can't tell LV "from now on, the default default value of an int32 is 1" but you can change the default default value of a class. This lead to a discussion of what the right decision should be about behaviors when the default default value is changed. Ultimately we settled on the behavior that a default value object should load as the default value, whatever the new default value happens to be. That decision has been criticized elsewhere on these forums, but four years later I'm comfortable that it was the right decision.
D) That raised the question of representation of the flattened string. The format of an object saved into the VI and the format of the binary string didn't have to be the same, and we could have chosen different behaviors. But once we decided that objects would include their version number in their flattened representation, it made sense to have the unflattening of binary strings and the loading of saved VIs have the same rules for mutating data. Thus the default value should remain the default value. We now have two options: To not bother saving the flat data when it is default or to save the flat data and compare against the default when we load into memory. The former saves a lot of disk space AND has significant performance advantages. Thus we decided that the Flatten To String primitive, which creates a binary string of the data, should not write down the default value.
E) When the XML prims were added in LV 8.6, we decided that the XML strings should again follow exactly the same mutation rules, and, again, the same performance trade-offs bent the discussion to not flatten the default value.
F) XML is meant to be human readable, but, as others in this thread have noted, not necessarily human editable. If you provide an editor to your users for modifying the data, that interface will allow you to change the values without caring whether the value was written down or not.
G) If you're using XML to share data between apps, you probably want to read this thread wherein I propose that you do NOT want to use the built-in LV XML primitives for XML that is going outside of LabVIEW, not because those prims are somehow flawed but rather that any built-in XML format is undesirable for data sharing (it's not a long thread if you want the arguments).
H) Using XML has allowed people to write apps that circumvent the privacy protections of the object data -- flatten to xml, modify the xml, then unflatten the data again. Hiccups such as "the default value is just missing" throw a wrench into this blatant violation of app security. In retrospect, the ability to flatten to XML (and to binary string, for that matter) probably should have been restricted to member VIs by default (author of the class could remove the restriction, just like we did with Create Data Value Reference in LV 2009) so that most classes wouldn't allow this hack. I've been talking to folks about whether or not it is too late to fix this mistake.
- 3
-
In fact, parent classes never know about their descendants. No data about any child classes is ever saved in a parent class, development or runtime environment.The parents don't have to know about the children at compile time. -
Kind of... without the selector being visible, there's no way to select the alternate functionality, so it might as well not exist. And without the selector, I think it is reasonable for any user of the the poly VI node to assume that all the functionality is available just by wiring inputs. Drawing the instance doesn't really help with those usability issues.There's always the option to draw the instance icon instead of the poly icon. If the icons are good enough to distinguish between the different instances then there's no problem, even if they have the same type inputs. -
Yeah. I don't like that at all. I know it works, but visually, it tends to be a problem for me. For one thing, the location of that feedback node floats around just like the stop terminal. For another thing, I still get twitchy about that one wire running backwards on the diagram.In newer versions, you can also just use a feedback node without a loop. -
I asked around. Here's the best answer I got:
Inlining with the token in LV 2009 can't handle front-panel terminals inside structures, locals variables, property nodes, invoke nodes, or control references.
I'll bet it is the FPTerms inside a structure node that is your problem as that would be the least obvious of items on this list.
-
Crelf & Daklu: You do realize that this is possible in LV today, right? And has been around since at least LV 6.0? The DAQ VIs are rife with this usage.For example, sometimes I like to have a poly parent that has children that are selectable based on the required functionality, not actual polymorphism (the inputs and outputs might be the same between the children).Create a PolyVI... On the configuration page for that PolyVI, there's a checkbox for "Show Selector by Default". This makes the poly VI instance selection ring appear under the node when you drop it. Then when users wire up to the node, they can select from the ring which bit of functionality they'd like to use. It's almost like having an action engine where the action is required to be a constant directly wired to the node. When I first learned about polyVIs, I filed a bug report that the poly VI wasn't broken even if two member VIs had the same inputs. Someone pointed this checkbox out to me, and I thought, ah, ok, now it makes sense. I let the bug report close as "not a bug." I did suggest that if there are two VIs added to the poly VI whose inputs are identical that the poly VI should be broken unless this checkbox is checked. That was rejected because it might break existing poly VIs that users had. Makes sense, but you should still be encouraged to use this checkbox for that case.
Maybe you knew all that, but it sounded like from your post (Daklu's in particular) that you didn't.
-
AQ made a post about this relationship recently in explaining some checking that occurs - I can't find the link yet - sorry! .
To be clear: the upcast coercion dot has no effect at runtime. It is not the same type of performance penalty that the coercion dot from int to double represents. We've talked about wanting two different coercion dots, but that's hard to provide since red appears to be the only color that most people can see in that small a space and there's no way to put a different pattern when you only have 6 pixels. So all the coercion dots look the same.
Typedef to not-typedef-but-still-same-type (and vice versa) is another coercion that has no runtime performance penalty.
- 1
-
Personal choice. Most documents you'll see from NI use the while loop, but I like being able to read, at the start of the loop, "This will only execute once." The stop terminal for the while loop can drift around a bit, and even if it was fixed in place, it's still at the right side of the loop instead of the left side. Wiring the N with a 1 means I recognize this type of loop as soon as I start reading it, instead of scanning across it to see the constant wired to the stop terminal.Out of curiosity, is there any particular reason you used a single iteration For loop over a single iteration While loop in Get Reference, or is it just your preferred way to build it?Under the hood, my understanding is that they both convert to the same assembly code, so it doesn't matter which you use.
- 1
-
Bingo.Just inherit from the class to be used and make it singleton in the last step.
-
If you mean "make the Singleton inherit from another class", that should work just fine.I like it. One issue I see that doesn't really seem to have a workaround is inheritance. I don't see how it could be done with this model, at least not easily.
If you mean "inherit from the Singleton", that's correct. This particular implementation is not intended to support inheriting from the Singleton. Singletons don't generally have inheritance in my experience -- there's supposed to only be one of them. If you want inheritance, there are variations on this theme that can be applied. All of them involve passing in some sort of "key" that says which Singleton you would like to use or moving to a "get and lock, then operate, then unlock" paradigm. But these are generally undesirable for singletons since even asking the question "which of several singletons do you want?" is somewhat ridiculous, since singleton should mean "there is only one."
-
It's been in my head in theory, but I hadn't had time to type it out. I declined to make it a shipping example in LV 2009 because the DVRs were new and I needed to see how they'd be accepted (or not) by the community. Including it (a cleaned up, more commented version of it) in 2010 is probable if the folks here think it solves the issues.(I'm curious, is that implementation something you've been sitting on for a while waiting to see if the community would 'discover' it or did you actually have to sit down and think about it for a while?) -
- Popular Post
- Popular Post
In LV 2009, this is how I would recommend that the Singleton pattern be implemented:
No wrapping library. No replication of VIs caused by having public wrappers and private implementations. No excessive copy overhead. And, yes, thread safety for parallel public calls.
This demo class implements three public functions: Set Path, Append Path (which does a read-modify-write) and Get Path.
Note that there is one minor issue with this implementation *if* (and only if) you have multiple top-level VIs all using the same central storage and the one that accesses the global first quits before the others are ready. The workaround solutions for that are ... problematic. It is in the set of "holes in the LV language" that we've been slowly patching o'er these many years.
- 4
-
I thought a fewton was something you slept on. :-)I encountered the word 'fewton' on wikipedia yesterday (it indeed is a 'singletone'-style object that has a limited number of maximum instances >1).
Dynamic Dispatching on User Events
in User Interface
Posted
OH NO. This is VERY BAD. That's going to have to be fixed in LV2010. That's a severe bug and I had no idea it existed until today. The ONLY reference on which it is safe -- and by safe I mean "won't cause a crash" -- is the DVRs. Take a look: