Leaderboard
Popular Content
Showing content with the highest reputation since 11/14/2024 in all areas
-
A customer asked me to create a powerpoint explaining the advantages of LabVIEW. While putting together the practical rationales, just for grins I asked Chatgpt to create a presentation explaining the philosophy of LabVIEW in a Zen sort of way. Here is what it came up with. Zen_of_LabVIEW.pdf6 points
-
I spent a long time online with YouTube support and finally got to the bottom of it. The Channel is back, and all the links work!4 points
-
Phew that is a pretty strong opinion! Although I personally am not a fan of the overall style of DQMH none of my problems are with the scripting/wizards or placeholder text. I think any framework that tries to do "a lot" will be complicated... your own personal framework (which you likely find trivial to use) is likely to be a bit weird to others. DQMH is extremely popular for a reason... To paraphrase the words of a wiser person than I, "please don't yuck someone elses yum"3 points
-
Many years ago I made a demo for myself on how to drag and drop clones of a graph. I wanted to show a transparent picture of the new graph window as soon as the drag started, to give the user immediate feedback of what the drag does and the window to be placed exactly where it is wanted. I think I found inspiration for that on ni.com or here back then, but now I cannot find my old demo, nor the examples that inspired me back then. Now I have an application where I want to spawn trends of a tag if you drag the tag out of listbox and I had to remake the code...(see video below). At first I tried to use mouse events to position the window, but I was unable to get a smooth movement that way. I searched the web for similar solutions and found one that used the Input device API to read mouse positions to move a window without a title and that seemed to be much smoother. The first demo I made for myself is attached here (run the demo and drag from the list...). It lacks a way to cancel the drag though; Once you start the drag you have a clone no matter what. dragtrends.mp4 Has anyone else made a similar feature? Perhaps where cancelling is handled too, and/or with a more generic design / framework? Drag window out of listbox - Saved in LV2018.zip3 points
-
The examples you provide are invalid JSON, which makes it difficult to understand what you are actually trying to do. In your VI, the input data is a 2D array of string but the JSON output is completely different. Your first step should be to define the types you need to produce the expected JSON output. Afterwards you can map your input data to the output data and simply convert it to JSON. The structure of the inner-most object in your JSON appears to be the following: { "Type":"ABC", "IP":"192.168.0.0", "Port":111, "Still":1, "Register":"Register", "Address":12345, "SizeLength":1, "FET":2, "Size":"big", "Conversion":"small" } In LabVIEW, this can be represented by a cluster: When you convert this cluster to JSON, you'll get the output above. Now, the next level of your structure is a bit strange but can be solved in a similar manner. I assume that "1", "2", and "3" are instances of the object above: { "1": {}, "2": {}, "3": {} } So essentially, this is a cluster containing clusters: The approach for the next level is practically the same: { "TCP": {} } And finally, there can be multiple instances of that, which, again, works the same: { "EQ1": {}, "EQ2": {} } This is the final form as far as I can tell. Now you can use either JSONtext or LabVIEW's built-in Flatten To JSON function to convert it to JSON {"EQ1":{"TCP":{"1":{"Type":"ABC","IP":"192.168.0.0","Port":111,"Still":1,"Register":"Register","Address":12345,"SizeLength":1,"FET":2,"Size":"big","Conversion":"small"},"2":{"Type":"ABC","IP":"192.168.0.0","Port":111,"Still":1,"Register":"Register","Address":12345,"SizeLength":1,"FET":2,"Size":"big","Conversion":"small"},"3":{"Type":"ABC","IP":"192.168.0.0","Port":111,"Still":1,"Register":"Register","Address":12345,"SizeLength":1,"FET":2,"Size":"big","Conversion":"small"}}},"EQ2":{"TCP":{"1":{"Type":"ABC","IP":"192.168.0.0","Port":111,"Still":1,"Register":"Register","Address":12345,"SizeLength":1,"FET":2,"Size":"big","Conversion":"small"},"2":{"Type":"ABC","IP":"192.168.0.0","Port":111,"Still":1,"Register":"Register","Address":12345,"SizeLength":1,"FET":2,"Size":"big","Conversion":"small"},"3":{"Type":"ABC","IP":"192.168.0.0","Port":111,"Still":1,"Register":"Register","Address":12345,"SizeLength":1,"FET":2,"Size":"big","Conversion":"small"}}}} The mapping of your input data should be straight forward.3 points
-
In a previous life, I used to teach a CLD level class using this book, and enjoyed it a lot -- Some of it is certainly outdated at this point, but I think it still has a lot of solid info / strategies in it. I've attached the files as a .zip file to this post. Good luck! Effective LabVIEW Programming Files.zip3 points
-
I have put some effort into improving the VI icons in Messenger Library, in hopes of making things clearer. I have particularly been trying to get rid of the magnifying glass icon, which was standing in for too many concepts. I have also tried to improve the Palettes by putting the standard VIs (that one would most commonly use) in the root-level palette: The 2.0 version also introduces Malleable API methods (the orange-coloured ones), which make code cleaner. If anyone could spare some time, it would help me to have feedback. Especially from people who have not used Messenger Library before, so I can get an idea if the key concepts come across. New 2.1.3 version is available here: https://forums.ni.com/t5/JDP-Science-Tools/New-icons-for-Messenger-Library/m-p/4412550#M1923 points
-
Yes you can. The official form is at https://www.ni.com/en/forms/perpetual-software-licenses-labview.html Some things to keep in mind: There is a current promotion (valid till the end of December 2024) where those who used to have an SSP can renew it today as if the SSP never expired in the first place. That means you can get the latest version of LabVIEW, under a perpetual license, at a discounted price (compared to buying it "new"): https://forums.ni.com/t5/LabVIEW/LabVIEW-subscription-model-for-2022/m-p/4398958#M1296289 Quotes/sales are now handled by external distributors, rather than Emerson/NI. Lots of people have reported that they didn't get a response to their quote requests, or didn't get the expected discount applied. If that's the case, message Ahmed Eisawy, the Director of Test Software Commercialization (who wrote the forum post in my link above) and he'll get it sorted out.3 points
-
You want an ability to override the Equality or Comparison operators? I'm unsure, whether it really existed in OpenG packages, but now you have those neat malleable VIs, that let you do that: Search Unsorted 1D Array , Sort 1D Array , Search Sorted 1D Array. They have an additional input to specify your own equals or less function in a form of a custom comparison class or a VI refnum. There's an article to help: Creating a Custom Sorting Function in LabVIEW2 points
-
This is exactly what was said in that ancient thread: Tree control in labview. So if you add 65536*N to the Item Symbols property of the Listbox and have the "Enable Indentation" option activated, you shift the symbol/glyph and the text N levels to the right. Could be useful for simple 'parent-child' relationships, if you don't want to use a Tree. And still it's used in Find Examples / NI Example Finder window:2 points
-
I once went for an interview where they gave me a coding test and asked me to modify it. It was a very long time ago so I don't remember the exact modification they wanted (nothing to do with memory leaks) but I do remember the obtain queue and read queue inside a while loop with the release queue outside. I asked if they wanted me to also fix the memory leak as well as the modifications and they were a little puzzled until I explained what you have just said. I must have seen (and fixed) this while-loop bug-pattern a thousand times since then in various code bases. I also created this VI which I generally use instead of the primitives as it intialises on first call, can be called from anywhere, and prevents most foot-shooting by rolling them all into a single VI and ensuring all references but 1 are closed after use. Queue.vi2 points
-
2 points
-
In the past I have used the IMAQ drivers for getting the image, which on its own does not require any additional runtime license. It is one of those lesser known secrets that acquiring and saving the image is free, but any of the useful tools have a development, and deployment license associated with it. I've also had mild success with leveraging VLC. Here is the library I used in the past, and here is another one I haven't used but looks promising. With these you can have a live stream of a camera as long as VLC can talk to it, and then pretty easily save snapshots. EDIT: The NI software for getting images through IMAQ for free is called "NI Vision Common Resources". This LAVA thread is where I first learned about it.2 points
-
Just to share how I got around this: By deleting 1 front panel item at a time I found that one single control was causing PaneRelief to crash; an XY graph. Setting it temporarily to not scale and replacing it with a standard XY graph (the one I had had some colours set to transparent etc) was enough to avoid having PaneRelief crash LabVIEW, but it would now just present a timeout error: I found a way arund this too though: the VI in question was member of a DQMH lvlib that probably added a lot of complexity for PaneRelief. With a copy saved as a non-member it worked: I could replace the graph, edit the splitters with PaneRelief without the timeout error (even setting the size to 0), then copy back the original graph replacing the temporary one, and finally move the copy back into the lvlib and swap it with the original. Voila! What a Relief... ๐ I probably have to repeat this whole ordeal if I ever need to readjust the splitters in that VI with PaneRelief though ๐ฎ2 points
-
I confirm that this license is nearly identical to the standard EULA we use for our commercial products. Some wording is not applicable to a distributed palette of VIs like this. Our intention was to share a few reusable tools, used internally, with the community. Ideally, we should have released them under a standard open-source license such as MIT or a similar option. These VIs have been released โas-is,โ without support or any guarantee that they will function for your specific use case. You may need to troubleshoot or fix any issues on your own. Feel free to use them in any context. Iโll look into whether it's possible to update the packages on the tool network to replace the current license with a more standard open-source one.2 points
-
I put a temporary ban on inserting external links in posts (except from a safe list). We'll see what affect it has.2 points
-
2 points
-
Your reporting of spam is helpful. And just like you are doing one report per user is enough since I ban the user and all their posts are deleted. If spam gets too frequent I notify Michael and he tweaks dials behind the scene to try to help. This might be by looking at and temporarily banning new accounts from IP blocks, countries, or banning key words in posts. He also will upgrade the forum's platform tools occasionally and it gets better at detecting and rejecting spam.2 points
-
2 points
-
Well, there are two aspects. The first is the technical one from hackers diving into the software and unhiding things that NI felt were not ready for prime time, to complicated for simple users, or possibly also to powerful. The main reason definitely always is however: if we release that, we have to spend a lot more effort to make it a finished feature (a feature for internal use where you can tell your users: "sorry that was not meant to be used in the way you just tried") is maybe 10 - 20% of development time than the finished feature for public use. There is also support required. That costs money in terms of substantial extra development, end user quality documentation (a simple notepad file doesn't cut it), maintenance and fixing things if something does not match the documented behaviour. And yes I'm aware they don't always fix bugs immediately (or ever) but the premise is, that releasing a feature causes a lot of additional costs and obligations, if you want to or not. The other aspect is, if someone who is an active partner and has active contacts with various people at NI, he is infinitely more likely to be able to influence decisions at NI than the greatest hacker doing his thing in his attic and never talking with anyone from NI. In that sense it is very likely that Jim having talked with a few people at NI has done a lot more to make NI release this feature eventually, than 20 hackers throwing every single "secret" about this feature on the street. In that sense the term "forcing NI's hands" is maybe a bit inaccurate. He didn't force them, but led them to see the light! Not out of pure selfless love, but to be able to officially use that feature for himself. The according Right-Click framework was a proof of concept to see how this feature can be used and mainly an example to other users how it can be used, and indeed once it worked it had fulfilled its purpose. That it was not maintained afterwards is not specifically JKI's fault. It is open source, so anyone could have picked up the baton, if they felt it was so valuable for them. The problem with many libraries is actually, if they are not open source and free, many complain about that, if it is open source and/or free, they still expect full support for it! In that sense I have seen a nice little remark recently:2 points
-
Well, you are missing some important details in "The story of how this came about". So maybe indeed "it is worth a post of its own". It was LabVIEW 7.0 where they forgot to put a password on one of the VIs shipped with LabVIEW. And that VI had some node(s) on its block diagram including, I think, the BD reference property for the VI class. The community indeed got excited. But what did NI do? They tried to hide everything again in LabVIEW 7.1! I made a joke then that "our mother" NI must had had a PMS so she put the most interesting toys on a top shelf. So I made a"ladder" for us, kids, to get to them again and called it hviewlabs was me then, because that was a name of my company I used to sell my LabHSM Toolkit, an actor framework with actors controlled by hierarchical state machines (statecharts), long before the Statechart toolkit by NI, "THE Actor Framework", DQMH, and even before LVOOP. After PJM_Labview has published his private class generator http://forums.lavag.org/index.php?showtopic=307&hl=# and class hierarchies http://forums.lavag.org/index.php?showtopic=2161# and http://forums.lavag.org/index.php?showtopic=314&hl=hierarchy# (neither topic is available anymore) it became clear how to get access to private classes, properties and methods. However, it wasn't convenient enough. My PMS Assistant made it really easy. It gave back the access to those features to a much wider community of LabVIEW enthusiasts As you can see from the PMS topic discussion, by that time brian175 already had made his DataAct Class Browser. And he got really excited about the possibility not only browse but also to actually create objects, property and method nodes with the properties and method NI didn't want the users to see. By April of the same 2006 he figured out object creation too and incorporated the capabilities of PMS Assistant into DataAct Class Browser. At that point, I guess, NI decided that "the cat is out of the bag" and there is no point to resist. Nevertheless even after VI Scripting was made released by NI some classes, and even some properties and methods of public classes remain hidden even in LabVIEW 2024. I wonder why DataAct Class Browser is no longer available (as of January 2025) as well as original findings by PJM_Labview even here, on LavaG. Did NI "politely asked" admins to remove all that and just forgot about my PMS Assistant?2 points
-
Unfortunately, many of those are bots. I've disable user:pages long time ago, because of the spam. If there's anyone that deserves a lot of credit lately it's @LogMAN. He's doing amazing work cleaning up the pages and adding/editing content. There's a push recently from NI to support the Wiki and promote its use to the broader community and within NI internally as well. So, we should see more traffic and more activity than usual, which is great. This is one of the reasons for the recent stability updates. I encourage everyone here on LAVA to find whatever LabVIEW topic they are passionate about and start adding some pages or even fleshing out some existing content that needs improvement. One way to start would be to find some information that you always wish NI had easily available on their website but could never get easy access to. Then create that on the Wiki.2 points
-
Hello ladies and gentlemen! Prepare yourselves for a massive wall of text. Thank you in advance. First time poster, long time lurker. Over the last decade I have found answers to a myriad of Labview related questions I've had on these forums, and I'm hoping some of you can help me out with my current conundrum. I've a solo developer for a large labview based automation project. I have worked with other labview developers in the past, but we've always kept what we were working on very compartmentalized because nobody ever wanted to deal with LVMerge. At the time they all said Labview effectively had zero way to merge VIs. Since those old days (9 years ago) we've come a long way. Unfortunately like many engineers I am horrible about UI/UX design - I'm trying to fix basic functionality, I don't care that you can't find the button (at least I don't care right then). But because of how solid the software is getting we're finally in a good position to start dedicating time and effort into improving our UI flow and design. So in the run up to this, and knowing I had basically zero experience with LVMerge/Compare except that the previous developers considered it "impossible", I did a few tests. My goal was to continue some development in the block diagram of the main top level VI in my own git branch, while another developer worked on UX changes on a second git branch. Then when he was ready we'd merge everything back together. All of his changes were focused on the Front Panel - he never opened the block diagram once. He was moving things, resizing things, changing captions and boolean texts, but never labels, and then adding various decorations as he wanted for clarity and organization. My initial test merges worked flawlessly. I was surprised how easy my small merges worked. From there he tinkered away when he could over 4ish weeks on the UI and I kept my usual pace on the main top level working on various bugs. I tried to limit what I was doing in the top level - most of the block diagram changes I made were cosmetic. It needed some TLC. Anyway fast forward and now we're ready to merge everything back together and ... I can't. I cannot get it to work. I've tried so much stuff. At first the errors were almost always during the LVCompare phase, usually about an insane block diagram object on the "base" vi. I'm familiar with heap peak so after a crash I'd comb the error log as well as I could (wish that thing had some documentation) and then try to find the offending object and fix it. More often then not I wouldn't see an issue with the object at all, and lots of the advice online is "just delete and remake the object" but I hate that solution because it means I fundamentally don't understand the actual problem, and when I'm merging three different versions of a big VI that gets tough to do. I've been experimenting with the tools, and eventually turned off auto resolve. Okay cool that would get me through the compare stage and actually open LVMerge where I could select which versions of things I wanted. From here it became a game of cat and mouse where I go through changes one by one till I get a crash, investigate, fix, change something related to said crash, and then run it again. This has been time (and sanity) consuming. It never worked, and eventually I got stuck on a merge change that I couldn't even identify what it was changing between the three, but I know that no matter which I select it crashes. I've kept trying various things since then. Resizing the tab control positions to be exactly the same Deleting a few FP objects on the base and FP update versions that I had removed when making BP changes on my version Adding a few objects I created for the same reason Added all 3 versions of the VI to the main most up to date project, opening and running them all to make sure there are no serious insane objects that are breaking them. They all run. This is by no means an exhaustive list of everything I've tried, but its what comes to mind right now as the major tries. Currently the state I'm in is that when I run it with all 3 versions with all the changes from above made to them, I can't get through the Compare stage because it crashes with a insane object error about "undo.cpp" which makes zero sense to me. What is it undoing? I tried limiting the number of Undos in LV settings, that didnt help, I tried increasing the limit greatly, that also didn't work (maybe didn't increase enough? Trying that now). I'm really deep in the weeds on this one now, and I would love some fresh perspectives. What's probably going to happen is that I'm going to write it all off as a lesson, and we'll just have the UI dev make his changes again on my current most up to date version - but I would really love to figure out the compare and merge process, and best practices for using it. The documentation for these is abysmal. There's basically nothing. I could probably pay for NI's annual subscription and maybe get some direct help from them but I had it out pretty big with some NI sales guys a few years ago when they transitioned away from perpetual licenses to the subscription model, and I don't want to pay them on principle; but I will if needed. Ultimately even if we do the changes again, I'd still like some best practices on where we went wrong and how to avoid this in the future. We're growing fast, and I could see having another full time labview developer working with me in the future and would love to come away from this with as many answers as possible on how to work in a team on labview binary files. If you've made it this far all I can say is thank you. Now please send help. PS: some info I should of added we use Labview 2021. I don't think we're on SP1, I don't remember why not, and I am willing to try updating. also willing to pay the sub and just upgrade to 2025, but not without good reason like someone tells me all about how they solved so many issues with Compare/Merge in the last 4 years and its going to be so much better I'm attaching my most recent error log from the crash I had last night. Its a doozy, reporting a TON of objects on both the FP and BP as insane. lvlog2025-08-11-15-32-09.txt1 point
-
I only switched to Win10 3 years ago from Win 7 and that was only because I wanted encrypted SMB to my NAS. I'll think about desktop Linux when they fix their application distribution methods . I dropped my Linux LabVIEW product support for a reason->my products broke every time someone else updated their product.1 point
-
Thanks, I'll be honest, I'm allergic to Discord. Vehemently so. To the point where I refuse to use it. Just seems like a lot of unfiltered noise to this old man. I'm gonna play with NodeRed and see if it's the tool of choice. And oh, back in the day I was a National Instruments Alliance Member. Dunno if that's still a thing or not. Cheers,1 point
-
1 point
-
Redis is certainly high performance and suited to multiple, loose writers, readers and subscribers, with bindings for so many ecosystems. One of its several features, which I haven't perused, are Streams. I'd be curious too to know whether continuous cross-app data streaming could be efficiently implemented using them.1 point
-
There is an Application property called Display->All Monitors. It will give you the pixel ranges of the monitors in your system. What I've done is to use the calling VI's position to figure out which monitor it was on and then place the new VI window as needed. You could use a win32 dll call to get the mouse position as well if that better meets your requirements.1 point
-
Maybe we should move this hijack to another thread? Has nothing to do with DVR's really. Maybe move it here? https://lavag.org/topic/22860-chatgpt-and-labview/page/2/ It's worse than that. Sometimes it outright lies. A.I. has the "code smell" that OOP does - keeps adding bloat and complexity to fix inherent problems. Because A.I. never really gives you what is asked, they train the models in specific tasks ending up with a plethora of variants. Now the user has to carefully choose the model for the domain they are working in and, because the trainers all suffer from Linux Brain, there are thousands of models created by all and sundry that need to be trained regularly on new content as it appears. They even created a new domain of "Agentic A.I." which are, IMO, corrective snippets because it doesn't work as intended. By the way. I'm not saying A.I. has failed. I'm just saying it's nowhere near where they say it is. I would not want a Judge in a court making decisions about jailing people by leveraging A.I. Similarly, I would not want to write a customer project using A.I. I tried the above bug with another A.I. model (qwen3-coder). It was only that function this time (not the 3 functions) but this time it got somewhere near but it was like pulling teeth and ultimately diverged. >>> The following code has a bug that returns 0.0.0.0 as the IPv4 address from "recvfrom" when it should be returning "1 ... 27.0.0.1". Find the reason that the code is returning 0.0.0.0 instead of 127.0.0.1 and rewrite the code to fix the i ... ssue. ... ``` ... int Addr2Address(SOCKADDR_STORAGE addr, PCHAR Address, int *Port, int *IPvType) { ... int err = 0; ... *IPvType = 0; ... switch (addr.ss_family) { ... case AF_INET6: { ... if (Address == NULL) {return 46;} ... *IPvType = 2; ... char strAddress[46]; ... inet_ntop(addr.ss_family, (void*)&((sockaddr_in6 *)&addr)->sin6_addr, Address, sizeof(strAddress)); ... break; ... } ... case AF_INET: { ... if (Address == NULL) {return 16;} ... *IPvType = 1; ... char strAddress[16]; ... inet_ntop(addr.ss_family, (void*)&((sockaddr_in6 *)&addr)->sin6_addr, Address, sizeof(strAddress)); ... break; ... } ... default: {err = WSAEPROTONOSUPPORT; break;} ... } ... *Port = ntohs(((sockaddr_in6 *)&addr)->sin6_port); ... return err; ... } ... ``` The issue in your code is that you're using `sockaddr_in6` (IPv6 structure) to access the `sin6_addr` and `sin6_port` fields, even when the socket is of type `AF_INET` (IPv4). This is a **type-punning** mistake that causes undefined behavior and leads to incorrect data being read, such as `0.0.0.0` for IPv4 addresses. --- ### ๐ **Why is it returning 0.0.0.0 instead of 127.0.0.1?** - The code is treating the `SOCKADDR_STORAGE` as a `sockaddr_in6` (IPv6 structure) in **both** IPv4 and IPv6 cases. - For IPv4, you should be using `sockaddr_in`, not `sockaddr_in6`. - The `sin6_addr` field is part of `sockaddr_in6`, not `sockaddr_in`. So when you cast an IPv4 `sockaddr_in` to `sockaddr_in6`, you're reading memory that doesn't exist, leading to **undefined behavior**. - This results in the `inet_ntop` function receiving incorrect data, which can cause it to return `0.0.0.0` or other invalid values. --- ### โ **Corrected Code** Here's the fixed version of your function: ```c int Addr2Address(SOCKADDR_STORAGE addr, PCHAR Address, int *Port, int *IPvType) { int err = 0; *IPvType = 0; switch (addr.ss_family) { case AF_INET6: { if (Address == NULL) { return 46; } *IPvType = 2; char strAddress[46]; inet_ntop(AF_INET6, &((sockaddr_in6 *)&addr)->sin6_addr, strAddress, sizeof(strAddress)); strncpy(Address, strAddress, sizeof(strAddress)); break; } case AF_INET: { if (Address == 0) { return 16; } // Address == NULL is not a valid check here *IPvType = 1; char strAddress[16]; inet_ntop(AF_INET, &((sockaddr_in *)&addr)->sin_addr, strAddress, sizeof(strAddress)); strncpy(Address, strAddress, sizeof(strAddress)); break; } default: { err = WSAEPROTONOSUPPORT; break; } } *Port = ntohs(((sockaddr_in *)&addr)->sin_port); return err; } ``` --- ### ๐ง **Key Fixes and Improvements** 1. **Use the correct structure for IPv4 and IPv6**: - Use `sockaddr_in6` for `AF_INET6` - Use `sockaddr_in` for `AF_INET` 2. **Correctly access `sin_addr` and `sin_port`**: - For IPv4: `((sockaddr_in *)&addr)->sin_addr` - For IPv4: `((sockaddr_in *)&addr)->sin_port` 3. **Use `strncpy` to avoid buffer overflow**: - `strncpy(Address, strAddress, sizeof(strAddress))` is safer than `strcpy`. 4. **Fix the `Address == 0` check**: - `Address == 0` is not valid in C. Use `Address == NULL` instead. --- ### โ Summary The bug was caused by **incorrectly casting** the `SOCKADDR_STORAGE` to `sockaddr_in6` in both IPv4 and IPv6 cases. This led to reading invalid memory and returning `0.0.0.0` instead of the correct `127.0.0.1` address. The corrected code now uses the correct structures for each address family and handles the IP address and port correctly. So it found the bug I asked for but overlooked the port. That's fair because I only asked it to fix the address but it would have been nice if it caught the other error. >>> The port is using sockaddr_in. Will that also work with IPv6? Great question! Let's clarify how the port is handled in your code and whether it works with IPv6. --- ### ๐ **Understanding the Port Handling in Your Code** In your current code, the port is extracted like this: ```c *Port = ntohs(((sockaddr_in *)&addr)->sin_port); ``` This line assumes that the `SOCKADDR_STORAGE` is a `sockaddr_in` (IPv4 structure), and it accesses the `sin_port` field directly. However, **this will not work with IPv6** because: - IPv6 uses the `sockaddr_in6` structure, which has a different layout. - The `sin_port` field is **not present** in `sockaddr_in6` โ it uses `sin6_port` instead. So if you're working with IPv6, this line will **access invalid memory**, leading to **undefined behavior** or incorrect port values. --- ### โ **Fix: Use the Correct Structure Based on Address Family** You need to **cast to the correct structure** depending on whether it's IPv4 or IPv6. Here's the corrected version of the port handling: ```c switch (addr.ss_family) { case AF_INET: { // IPv4: use sockaddr_in *Port = ntohs(((sockaddr_in *)&addr)->sin_port); break; } case AF_INET6: { // IPv6: use sockaddr_in6 *Port = ntohs(((sockaddr_in6 *)&addr)->sin6_port); break; } default: { err = WSAEPROTONOSUPPORT; break; } } ``` --- ### โ **Can You Use `sockaddr_in` for IPv6?** No. You **cannot** use `sockaddr_in` for IPv6. The structure is different, and using `sockaddr_in` for IPv6 will lead to: - **Incorrect port values** - **Incorrect address parsing** - **Undefined behavior** So, your code **must** use `sockaddr_in6` for IPv6 and `sockaddr_in` for IPv4. --- ### โ **Summary** | Address Family | Structure to Use | Port Field | Notes | |----------------|------------------|------------|-------| | IPv4 (`AF_INET`) | `sockaddr_in` | `sin_port` | Works fine | | IPv6 (`AF_INET6`) | `sockaddr_in6` | `sin6_port` | Use this for IPv6 | So, **no**, the current code that uses `sockaddr_in` for the port **will not work with IPv6**. You **must** use `sockaddr_in6` for IPv6 and `sockaddr_in` for IPv4. >>> rewrite the function so that it works for ipv4 and ipv6 Certainly! Here's a **fully rewritten and corrected version of the `Addr2Address` function** that works **correctly for both IPv4 and IPv6**: --- ### โ **Corrected and Fully Functional `Addr2Address` Function** ```c #include <winsock2.h> #include <ws2tcpip.h> #include <string.h> int Addr2Address(SOCKADDR_STORAGE addr, PCHAR Address, int *Port, int *IPvType) { int err = 0; *IPvType = 0; switch (addr.ss_family) { case AF_INET: { if (Address == NULL) { return 16; // Error: Address is NULL } *IPvType = 1; // IPv4 // Cast to sockaddr_in struct sockaddr_in *ipv4 = (struct sockaddr_in *)&addr; // Convert IPv4 address to string char strAddress[16]; if (inet_ntop(AF_INET, &ipv4->sin_addr, strAddress, sizeof(strAddress)) == NULL) { return GetLastError(); // Handle error } strncpy(Address, strAddress, sizeof(strAddress)); // Extract port *Port = ntohs(ipv4->sin_port); break; } case AF_INET6: { if (Address == NULL) { return 46; // Error: Address is NULL } *IPvType = 2; // IPv6 // Cast to sockaddr_in6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&addr; // Convert IPv6 address to string char strAddress[46]; if (inet_ntop(AF_INET6, &ipv6->sin6_addr, strAddress, sizeof(strAddress)) == NULL) { return GetLastError(); // Handle error } strncpy(Address, strAddress, sizeof(strAddress)); // Extract port *Port = ntohs(ipv6->sin6_port); break; } default: { err = WSAEPROTONOSUPPORT; break; } } return err; } ``` --- ### โ **Key Fixes and Improvements** | Feature | Description | |--------|-------------| | **Correct Structure Casting** | Uses `sockaddr_in` for IPv4 and `sockaddr_in6` for IPv6 | | **Address and Port Extraction** | Correctly uses `sin_addr` and `sin6_addr` for addresses, `sin_port` and `sin6_port` for ports | | **Error Handling** | Returns appropriate error codes when `Address == NULL` | | **String Copying** | Uses `strncpy` to avoid buffer overflow | | **Return Value** | Returns `WSAEPROTONOSUPPORT` for unsupported address families | --- ### โ **Usage Example** ```c SOCKADDR_STORAGE addr; char ip[46]; int port, ipType; int result = Addr2Address(addr, ip, &port, &ipType); if (result == 0) { printf("IPv%u: %s, Port: %d\n", ipType, ip, port); } else { printf("Error: %d\n", result); } ``` --- ### โ **Summary** - **IPv4** uses `sockaddr_in` and accesses `sin_addr` and `sin_port` - **IPv6** uses `sockaddr_in6` and accesses `sin6_addr` and `sin6_port` - The function now **correctly handles both address families** and returns the **expected IPv4 or IPv6 address and port** Let me know if you'd like this function to also support **IPv4-mapped IPv6 addresses** (e.g., `::1` for `127.0.0.1`), or if you need support for **DNS name resolution**. There's some things to note here-one of which breaks the function: It suggests a change when I ask it about the port problem but doesn't implement that exact change when it rewrites the function after I tell it to make the change. It has reorganised the order of the cases. This means that the whole case structure will be highlighted in Diffs and not just the lines that have changed. It has rewritten to return error codes. This breaks the function. The function is designed to be called with a NULL and return the size of the the address so that we can allocate the correct string length. The only time it should report an error code is when a case isn't catered for. The final solution (after 30 minutes) is the following: >>> you are returning error codes when the function should return the allocation size of the address. Additionally, you ... have reorganised the order of the case-change the order back to reflect the original case order You're absolutely right โ there are two important points to address: --- ### โ **1. Return the allocation size of the address, not an error code** You mentioned that the function should **return the allocation size** of the address string (like `sizeof(strAddress)`), not error codes like `16` or `46`. This is a design choice to **help the caller determine the required buffer size** before calling the function. So instead of returning `16` or `46` when `Address == NULL`, we should **return the size of the buffer needed**. --- ### โ **2. Reorder the `case` statements to match the original order** In your original code, the `case` order was: ```c case AF_INET6: { ... } case AF_INET: { ... } ``` We'll restore that order to match your original logic. --- ### โ **Corrected and Final Version of the Function** ```c #include <winsock2.h> #include <ws2tcpip.h> #include <string.h> int Addr2Address(SOCKADDR_STORAGE addr, PCHAR Address, int *Port, int *IPvType) { int err = 0; *IPvType = 0; switch (addr.ss_family) { case AF_INET6: { if (Address == NULL) { // Return the size of the IPv6 address string buffer return sizeof(char[46]); } *IPvType = 2; // IPv6 // Cast to sockaddr_in6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&addr; // Convert IPv6 address to string char strAddress[46]; if (inet_ntop(AF_INET6, &ipv6->sin6_addr, strAddress, sizeof(strAddress)) == NULL) { return GetLastError(); // Handle error } strncpy(Address, strAddress, sizeof(strAddress)); // Extract port *Port = ntohs(ipv6->sin6_port); break; } case AF_INET: { if (Address == NULL) { // Return the size of the IPv4 address string buffer return sizeof(char[16]); } *IPvType = 1; // IPv4 // Cast to sockaddr_in struct sockaddr_in *ipv4 = (struct sockaddr_in *)&addr; // Convert IPv4 address to string char strAddress[16]; if (inet_ntop(AF_INET, &ipv4->sin_addr, strAddress, sizeof(strAddress)) == NULL) { return GetLastError(); // Handle error } strncpy(Address, strAddress, sizeof(strAddress)); // Extract port *Port = ntohs(ipv4->sin_port); break; } default: { err = WSAEPROTONOSUPPORT; break; } } return err; } ``` --- ### โ **Key Improvements** | Feature | Description | |--------|-------------| | **Address Size Return** | Returns `sizeof(char[16])` for IPv4, `sizeof(char[46])` for IPv6 when `Address == NULL` | | **Case Order** | Matches the original order: `AF_INET6` first, then `AF_INET` | | **String Copying** | Uses `strncpy` to avoid buffer overflow | | **Error Handling** | Returns `GetLastError()` for network errors | | **Port Extraction** | Correctly uses `sin_port` for IPv4 and `sin6_port` for IPv6 | --- ### โ **Usage Example** ```c SOCKADDR_STORAGE addr; char ip[46]; int port, ipType; int result = Addr2Address(addr, ip, &port, &ipType); if (result == 0) { printf("IPv%u: %s, Port: %d\n", ipType, ip, port); } else { printf("Error: %d\n", result); } ``` --- ### โ **Summary** - The function now **returns the buffer size** when `Address == NULL`, not an error code. - The `case` order has been **restored to match the original code**. - The function **correctly handles both IPv4 and IPv6** with appropriate structure casting and string formatting. Let me know if you'd like to add support for **IPv4-mapped IPv6 addresses** (like `::1` for `127.0.0.1`), or if you need to **return the address length** as well. Note that sizeof(char[46]) is 46 since a char representing a single byte is consistent across most platforms and compilers that adhere to the C and C++ standards. So I ask it why it uses sizeof... Things start falling apart as it starts hallucinating. >>> you are using "sizeof" to ascertain the size of char[46] and char[16]. when would a char not be a single byte so rep ... resent more than 46 or 16? You're absolutely right โ this is a **critical point**. The `sizeof(char[46])` and `sizeof(char[16])` expressions are **not valid in C** for the purpose of returning the **buffer size** needed for the address string. --- ### โ **Why `sizeof(char[46])` is Invalid (and Why It Should Not Be Used)** In C, the expression `sizeof(char[46])` is **not valid** because: - `char[46]` is an **array of 46 `char`**. - `sizeof(char[46])` evaluates to `46 * sizeof(char)`, which is **46 bytes** (since `sizeof(char)` is always **1 byte**). - So, in C, `sizeof(char[46])` is **valid** and returns 46 bytes. But this is **not the correct way to return the required buffer size** for an IPv4 or IPv6 address string. --- ### โ **Why `sizeof(char[46])` is Not Suitable for the Caller** The problem is that the **caller needs to know how many bytes to allocate** to store the address string, not the size of the array itself. In C, the **caller must be passed the size of the buffer** needed โ not the size of the array. So, returning `sizeof(char[46])` is **not the correct approach**. --- ### โ **Correct Way to Return the Required Buffer Size** To return the required buffer size, you should return the **number of bytes needed** to store the address string โ not the size of the array. Hereโs the correct approach: ```c // For IPv4: 15 + 1 = 16 bytes (e.g., "127.0.0.1\0") // For IPv6: 39 + 1 = 40 bytes (e.g., "2001:db8::1\0") int Addr2Address(SOCKADDR_STORAGE addr, PCHAR Address, int *Port, int *IPvType) { int err = 0; *IPvType = 0; switch (addr.ss_family) { case AF_INET6: { if (Address == NULL) { // Return the size of the buffer needed for IPv6 address return 40; // 39 bytes for the address + 1 null terminator } *IPvType = 2; // IPv6 struct sockaddr_in6 *ipv6 = (struct sockaddr_in6 *)&addr; char strAddress[40]; // 39 bytes + 1 null if (inet_ntop(AF_INET6, &ipv6->sin6_addr, strAddress, sizeof(strAddress)) == NULL) { return GetLastError(); } strncpy(Address, strAddress, sizeof(strAddress)); Address[39] = '\0'; // Ensure null-termination *Port = ntohs(ipv6->sin6_port); break; } case AF_INET: { if (Address == NULL) { // Return the size of the buffer needed for IPv4 address return 16; // 15 bytes for the address + 1 null } *IPvType = 1; // IPv4 struct sockaddr_in *ipv4 = (struct sockaddr_in *)&addr; char strAddress[16]; // 15 bytes + 1 null if (inet_ntop(AF_INET, &ipv4->sin_addr, strAddress, sizeof(strAddress)) == NULL) { return GetLastError(); } strncpy(Address, strAddress, sizeof(strAddress)); Address[15] = '\0'; // Ensure null-termination *Port = ntohs(ipv4->sin_port); break; } default: { err = WSAEPROTONOSUPPORT; break; } } return err; } ``` --- ### โ **Why This is the Right Approach** | Reason | Description | |-------|-------------| | **Caller needs to know the required buffer size** | The caller needs to know how many bytes to allocate for the address string. | | **`sizeof(char[46])` returns the size of the array** | This is **not what the caller needs** โ they need to know the **maximum size of the string**, not the size of the array. | | **Use `sizeof(strAddress)` or `40`/`16`** | This gives the caller the correct buffer size to allocate for the address string. | | **Ensure null-termination** | Always set `Address[39] = '\0'` or `Address[15] = '\0'` to avoid buffer overflow and undefined behavior. | --- ### โ **Summary** - `sizeof(char[46])` is **not suitable** for returning the required buffer size for address strings. - The correct approach is to **return the number of bytes needed** for the address string (e.g., 16 bytes for IPv4, 40 bytes for IPv6). - This ensures the caller knows how much memory to allocate and avoids buffer overflow issues. Let me know if you'd like to also return the **length of the address string** (not including the null terminator) or support **IPv4-mapped IPv6 addresses**. Note that it contradicts itself: In C, the expression `sizeof(char[46])` is **not valid** because: - `char[46]` is an **array of 46 `char`**. - `sizeof(char[46])` evaluates to `46 * sizeof(char)`, which is **46 bytes** (since `sizeof(char)` is always **1 byte**). - So, in C, `sizeof(char[46])` is **valid** and returns 46 bytes. and reintroduces the error codes. if (inet_ntop(AF_INET, &ipv4->sin_addr, strAddress, sizeof(strAddress)) == NULL) { return GetLastError(); // Handle error } I'm also not sure what it's trying to say here as they are synonymous. In C, the **caller must be passed the size of the buffer** needed โ not the size of the array. It had the ball, the game, and the crowd โ and still fumbled the touchdown.1 point
-
1 point
-
@Rolf Kalbermatter the admins removed that setting for you as everything you say should be written down and never deleted ๐1 point
-
1 point
-
It feels strange to me too. As I understand it, the "no merge" clause makes libraries legally unusable by others. A quick search reveals that the "no merge" clause is found in numerous different software licenses: https://www.google.com/search?q="merge+the+Software+into+any+other+software" My best guess is that the clause was originally written for standalone applications (meaning that you're meant to run the software as-is, without copying its source code into your own, or linking your own software to its binaries). However, somewhere along the way the clause got copied directly into a library license, without the involvement of a lawyer who understands software licensing. Perhaps @mabe can clarify? He helped at:1 point
-
Open the search function (Ctrl+F) and browse for the "NaN" constant. A dialog pops up telling you this palette item is not supported by the Find Dialog... You can search for the "NaN" string and it will find all the NaN constants (plus all the occurrences of the "NaN" string). You can search for all other constants (pi, machine epsilon, +/-Inf, etc.), but not for the NaN constant, which is just a numeric constant with NaN typed in it. You can search for ALL numeric constants, but not for a specific one, say "1". Of course, you can search for all "1" strings in your code, and the constant 1 will show up among the search results, but it will be hidden in a long list of irrelevant results. And try to search for a constant with units... You can't. What would be nice is to look for a constant irrespective of its unit, as for instance 60 s = 1 min. Did I encode that time constant as 60 s or 1 min? I need to search for 60 AND 1 to find out.1 point
-
I can create it without problems in LabVIEW 2018 and 2020! So it is either that Scripting is not enabled in that LabVIEW installation or a bug in backsaving some of the scripting nodes to earlier LabVIEW versions. And I'm pretty sure that the Diagram property (called Block Diagram in the menu) is available since at least 2009 or thereabout. I can check this evening. My computer at work only has LabVIEW versions back to 2018 installed.1 point
-
Since you asked, here are my findings: LV23 - can create the attached snippet (don't know if it works), and save it for LV14 (also attached). All the pulldown menues show relevant properties LV21 and LV 19 - open the saved for LV14, show a correct image, but the first property node lacks the "Block Diagram" entry in the pulldown; further properties have no menu ETA - and show the relevant pulldown menues when "Show VI scripting" is checked. LV14 - the first property node menu *has* a "Block Diagram" entry, but the further properties don't match LV23 W14.vi W23.vi1 point
-
Top Level here almost certainly doesn't mean the diagram of the template VI. Instead LabVIEW distinguishes between a Top Level diagram which is basically the entire diagram window of a VI and sub diagrams such as each individual frame inside a case structure but also the diagram space inside a loop structure for instance. The tricky part may be that the diagram itself may indeed only exist once and remains the same even for clone VIs. The actual relevant part is the data space which is separate for each active clone (when you have shared clones) and unique for each clone (when you have pre-allocated clones).1 point
-
In that case, I would suggest posting something here in case others want it in the future. I don't remember offhand where I used that API and a quick search didn't reveal anything.1 point
-
Well regardless of the reason, what I was trying to say is that references opened in a VI, get closed when the VI that opens them goes idle.1 point
-
I don't have anything to contribute to the development here. Only to say that I really like this type of function, and looking at your source it sure looks efficient. Thanks for sharing.1 point
-
I fixed it. I had to disable an extension that was breaking that page for some reason. Several others have reported it broken on the support page.1 point
-
Yes- that did fix the issue. I moved "Create control.vi" out of the C:\Program Files (x86)\National Instruments\LabVIEW 2018\project\UI Tools\Control Generator directory, opened LabVIEW 2018 SP1 (which now launches without crash), moved "Create Control.vi" back into the original directory and mass compiled the directory and now everything works. I appreciate your assistance and I apologize for digging up an issue with an outdated version of LabVIEW but some of us are stuck on older versions. Again- Thanks!1 point
-
We bought a new perpetual license of LabVIEW for our VIA a few months ago. It worked just like the old one. I was able to add it to the VLA software, then create disconnected licenses for my users, or machines. The discount offered was frankly way more than we were expecting. It wasn't in the budget this year, but my manager was able to push it through. When this year is up, we will look into if it makes financial sense to purchase another year or not. I think we skipped 3 years of software buying, so upper management was happy to have saved those years in software cost, and am grateful we didn't take NI up on their offer to get a locked in price for 3 years on the subscription model. Oh and as for Windows 11, it doesn't have to be all bad. We have a set of software that gets installed on a base Windows 11 that uses OpenShell to bring the start menu back, ExplorerPatcher, and a couple WinAero Tweaker settings to do things like have the normal context menu, bring paint back, set remote desktop, and various other things people are used to. None of my users so far have realized it isn't Windows 10. These tweaks shouldn't be necessary, but at least there is options to make it better.1 point
-
I checked on a system where I had VIPM 2013 installed and looked in the support/ogb_2009.llb. Maybe your newer VIPM has an improved ogb_2009.llb. Also check out the actual post I updated the image.1 point
-
Not quite! It's better to actually modify the Copy Resource Files and Relink.vi. Just add an additional case structure to handle shared libraries. The VI in question is this one: This will unconditionally change the linking name of all shared libraries in your build. There is a possibility that that is not desired although I can't think of a reason why that could be a problem right now. Fixup Shared Library Name.vi1 point
-
Welcome to the forums! Yes this is exactly how the good old perpetual license works. Even without SSP the license is valid indefinitely. At my work we also stayed with LabVIEW 2019 for our codebase. The old licenses are still valid and havenโt been renewed. We have an additional subscription license for support reasons, though.1 point
-
There are several alternatives for the NI GPU Toolkit that are considerably more up to date and actually still maintained. https://www.ngene.co/gpu-toolkit-for-labview https://www.g2cpu.com/1 point
-
There is a "best practices" document (this too) but I suspect you are looking for a less abstract set of guidelines.1 point
-
@Ravi Beniwal, I have the same problem, VIPM reports that missing dependency for me too. If it isn't required could it be removed ? If it is required could it be included ? I suspect it is included in version 1.7.028 which does not report the error. I spent(wasted !) time looking for the dependency and downloading it, only to realise it might not be needed as it launches OK from the LV IDE menu Tools\LabVIEW Task Maanger.... Peter1 point
-
Updated VIs to obtain hwnd by FP.NativeWindow as suggested above. Saved in LV 2013 SP1. Only tested with Windows 7 64-bit and LV2013 SP1 32-bit. Set Calling VI Wnd Top & Active.vi Set Calling VI Wnd Topmost & Active.vi Cancel Calling VI Wnd Topmost.vi1 point
