Jump to content

GregFreeman

Members
  • Content Count

    322
  • Joined

  • Last visited

  • Days Won

    5

Everything posted by GregFreeman

  1. I don't believe there are any DVRs, but I can't be certain. There are however various references types everywhere. That being said, for now I have just extended the timeout and it seems to be fine. I am going to assume there is something going on akin to what you mentioned in some way, shape, or form. The code base is a tangled mess and trying to get to root cause may just be a futile exercise.
  2. I am working with some legacy code that I didn't write and am seeing a strange issue but really am not sure where it has come from. In the last year I have worked with this code, this hasn't come up and I haven't changed anything that I think would effect it. In this code, VIs are launched dynamically from a launcher loop using the Run VI method. When the dynamic VI is finished, it sends an event back to the launcher loop, which is then responsible for dynamically launching the next VI. When the launcher loop receives the message that the dynamically launched VI is finished, it polls that
  3. Yes, basically. The deeper I get into this I think what I need to solve my problems are generics, to get generality and combine it with type safety, and I simply don't have them, so I have to work within the tools I am given.
  4. I agree and I didn't mean to imply they are mutually exclusive. I assume you mean the fact that you have to create many messages or many refnums which results in a lot of extra classes/code? If so, I do somewhat agree with this. If not, maybe you can provide some more detail into the "why?" I also completely agree with this, I am just partial to leveraging built in mechanisms where I can, and I think it makes for clean, readable code with native structures. That's not to say there aren't other viable, valuable solutions. But it is the reason why I tend to lean towards user even
  5. Thanks! The mediator pattern may be a good option. The main drawback I have with any sort of command pattern is that I can't leverage a huge benefit of user events which is the fact that you can have multiple processes register, and only have to send the message out once for them all to receive it. It's great to be able to send a single message and have 3 different windows receive it, my logger receive it, etc and all handle it differently. The command pattern I believe would require you to dynamic dispatch on the messages Do.vi to get a concrete message type, and then immediately pass that co
  6. Yes, and not only this but you are essentially required to expose a refnum to a non-owner in order for it to register, which has never sat correctly with me. I think I should just live with it since I've revisited this what seems like hundreds of times. I've tried wrapping the logic up in a class with register methods exposed, but it becomes more difficult if a VI is launched asynchronously. In this case you want the parallel VI to create its references so they are tied to the lifetime of that VI, not the caller. Because classes are by value, if you do this you have to pass back all the c
  7. I have been going back and forth on the best method for handling shared data between two processes which may or may not exist at the same time. Assume you have processes A and B, and process A is running, B is not. At some point in the future when B begins running, A needs to register for some events from B. I see two ways to handle this. The first way is aggregation. Some parent process that has visibility of both A and B is responsible for creating the user event refnum and passing it to both processes if/when they are created. This is a simple solution but can be a bit ugly in my opinion, s
  8. FWIW, I have always just stored this in a variant in the class private data, and written a private wrapper VI to convert to and from the reference/variant. It makes me twitch slightly every time I do it, but it's functional so that's good enough for me. It's ironic because I just used this the other day, and was debating posting a question on this subject -- whether or not anyone else was using start async call nodes with wait on async call to run things like dialogs. I have been using this to manage the shutdown sequence of windows or processes that run dynamically, even if I don't nee
  9. Sounds good. I have decided to just register for the events scoped to the parent, in the childrens' event structures. It does result in some duplicate event handling code between children, which I'd like to live in the parent, but it's not really that big a deal. I may refactor to use something more like the actor framework for this class, but I think with the minimal number of events I don't get a whole lot of lift from refactoring
  10. Yes, this is the solution I keep wanting to land on except it doesn't cover the case where Event C wants to do something with parent state which is updated from an event. Using your example, assume event A is triggered and the string value becomes state that belongs to the parent. Now assume event C triggers writing that string to a file. The child event handler loop will not have access to the string that was updated in the parent event handler, since the wire was split. I am starting to think that I am trying to make what is more of a by-reference paradigm and fit it into a by value language
  11. I have struggled with this for a long time, but haven't really come up with a solution. I actually found an old message I sent to AQ about 6 years ago (wow) which is related to this, but his response fell by the wayside and I want to revisit it. In that case, it was about dynamic events to reuse code that is part of a Dialog, much like Windows would use OnOK and OnCancel callbacks that were not coupled to a specific dialog, but instead took a dynamic reference to controls on the child dialog. Assume you have a parent class Base and a child class Child. Base has events A and B, Child has
  12. Got it, this makes sense. Thanks! I suppose from this output when I create 'c file I just didn't correctly reverse engineer the data structures in terms of what LabVIEW wanted. TD1 has a TD2 not a TD2Handle. Looking at it again with your clarification makes sense typedef struct { int32_t numPorts; LStrHandle Sn; } TD2; typedef struct { int32_t dimSize; TD2 elt[1]; } TD1; typedef TD1 **TD1Hdl;
  13. I've taken this one step further, because I realized I will need to return more than just an array of strings, but instead return an array of clusters. I have modified the dll, and sprintf statement seems to output the correct values, but I'm getting garbage back in LabVIEW. My best guess is it has something to do with what my handles are pointing at, but I haven't been able to figure out the issue. /*Free an enumeration Linked List*/ void EXPORT_API iir_usb_relay_device_free_enumerate(IIR_USB_RELAY_DEVICE_INFO_T* info) { //usb_relay_device_free_enumerate((struct usb_relay_device_info*)in
  14. Very helpful, now it's working. Another big problem I realized is that I had the CLFN set to WINAPI, not C, calling convention 🤦‍♂️
  15. Ah, that makes sense. Needs to be a pointer to the handle... I am not currently crashing mid-function anymore, but i do crash when it reaches the end. I have attached the code as it stands now. I'm creating a linked list myself since I don't have access to the hardware. I am seeing something strange in the visual studio debugger. Notice the value of the str variable in hdl has some junk after "efgh." It's making me think something in the resize and MoveBlock aren't quite right, but I can't figure out what. int EXPORT_API iir_get_serial_numbers(LStrArrayHandle *arr) { MgErr er
  16. Actually, I did this yesterday to try and figure out the datatypes 😂. I thought some other magic was happening but I suppose not. I guess my question then becomes, why do we choose the particular sizes for uPtr, and how does that translate to our struct size? I suppose I'm just not understanding the relation between uPtr, the cast of arr to UHandle, and 'n' in terms of what is being done inside that resize function. Anyways, unfortunately I keep crashing here: err = NumericArrayResize(uB, 1, (UHandle*)pH, len); I did get a compiler error here: pH = (**strArr)->e
  17. Looking at the API, I believe this is the case. @Rolf Kalbermatter would you mind explaining what is happening with the first NumericArrayResize? The one for the string buffer is pretty self explanatory, but I don't quite understand how the first one that resizes the LStrArrayHandle works. How does the function know how to resize memory for a data structure that we have defined ourselves?
  18. Very helpful, both of you. Thanks! Rolf, you mention this will only work if the linked list doesn't change in the background, which of course makes sense. Theoretically it won't change, but it is coming from another API, so I assume there is no way to handle keeping this safe? Even if I were to loop through the linked list immediately and make copies of the items and/or serial numbers, during my looping there is still the risk it could change, correct?
  19. Thanks very much. This is really helpful and makes a lot of sense. My only follow up question is, is it necessary to size the LStrHandle to fit the string and use strcpy? Or can I just assign h -> str to point at the address of s_deviceInfo -> serial_number?
  20. I have a DLL for a device which holds a linked list of structs. Obviously I cannot pass this to LabVIEW, but all I really need are the serial numbers from within the struct. So my idea is to write a wrapper to map the serial numbers to a string array and return them from a dll. Due to my lack of experience with C and lack of examples with the LabVIEW memory manager dll, I'm having quite a hard time. Because the linked list can be of a dynamic length, I am not sure how to handle the memory allocation. This is my attempt so far. My questions are 1) How do I properly size DSNewHandle to
  21. Nope, we have explicit, static registrations for controls in our subpanels. Nothing dynamic or using references. We did potentially trace things back to our error logger. We have a subVI that just throws errors in a queue and then a process that flushes the queue every few seconds and logs them. Seems when we aren't logging errors the problem goes away, so I'm not really sure what's going on. Possibly something there blocking our UI thread somehow and events getting missed but the flush and write happens within 100 ms so it definitely still seems a bit strange. Right now it seems the pro
  22. I have an application that is using subpanels, and I am having some issues where they seem to be missing button clicks. This is sporadic and not isolated to one specific button but seems to happen throughout the application on various screens. I look in the event inspector window and the value change never fires when these events are missed, so it's as if whatever is managing these events is missing it completely. After two or three clicks it will take. I know it's tough to help without a reproducible case, so I am mostly posting this to see if others have run into this behavior because I have
  23. Thanks very much everyone. And I really appreciate the UML -- very helpful
  24. Sorry for the ambiguous title...hard to convey the problem without description. Right now I have an application that takes various measurements, but for now I'm going to focus on current. The issue is that there are many devices that can take current measurements, which our customer will swap out. But they don't necessarily have a parent/child relationship. Everything I think of screams to me "This would be easy with interfaces" but I'm really hoping there is some solution with composition. The application has a lot of situations where there is a power supply, but they may use a DVM
  25. For some reason this isn't working for me on Windows 10. Any thoughts? I've installed the latest version and already had the 2016 runtime installed.
×
×
  • Create New...

Important Information

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