-
Posts
353 -
Joined
-
Last visited
-
Days Won
35
Content Type
Profiles
Forums
Downloads
Gallery
Everything posted by dadreamer
-
event structure localization issue on OpenSuse
dadreamer replied to Antoine Chalons's topic in Linux
Your issue with Event Structure names reminds me this thread - LabVIEW Event names are completely off. Even though that was experienced on Windows and the OP solved the issue by removing LabVIEW and cleaning up the system with msiBlast. Might it be that something didn't get installed properly in your case?.. -
Getting a list of sound devices in the system
dadreamer replied to MartinMcD's topic in LabVIEW General
Maybe it's time to try WaveIO library written by Christian Zeitnitz then? -
It's just that NI designed those JPEGToLVImageDataPreflight and JPEGToLVImageData functions to run in UI thread. I don't know whether it's safe to set the CLFNs to "Run in any thread" and use it, because we don't have the sources. You could test it on your own and see. But it's known that most of WinAPI functions are reentrant, thus you may freely use WIC or GDI+ from multiple threads simultaneously. So, to re-invent JPEG reading VI with WIC this thread could be a starting point (along with Decode Image Stream VI diagram as an example). For GDI+ this thread becomes useful, but this way requires writing a small DLL to use GDI classes. I don't recommend using .NET nodes in LabVIEW here, as the execution speed is that important for you.
-
You could probably take a look at this: https://forums.ni.com/t5/Machine-Vision/Convert-JPEG-image-in-memory-to-Imaq-Image/m-p/3786705#M51129 For PNGs there are already native PNG Data to LV Image VI and LV Image to PNG Data VI.
-
Another option would be to get NI's hands on IntervalZero RTX64 product, which is able to turn any Windows-driven computer into a real-time target. That would definitely require writing kernel drivers for NI hardware and some utilities/wrappers for LabVIEW to interact with the drivers through user-space libraries. Of course, the latter is possible now with CLFN's but it's not that user-friendly, because focuses mainly on C/C++ programing. Not to mention, that a limited subset of hardware is supported.
-
Also take into account the bitness of your ActiveX libraries, that you're going to use. If you want to use 32-bit libraries, then you invoke "%systemroot%\SysWoW64\regsvr32.exe" in your command shell. For 64-bit libraries you invoke "%systemroot%\System32\regsvr32.exe" to register. That is true on 64-bit Windows. Better do this manually and, of course, with administrator privileges (otherwise it may not register or may report "fake" success).
-
You also can create the buttons in run-time with the means of .NET - the basic example is here (of course, you need to attach the event callback (handler) to your button(s) to be able to catch the button events).
-
Can Queues be accessed through CIN?
dadreamer replied to Taylorh140's topic in Calling External Code
If you meant me, then no, I even didn't use your conversations with Jim Kring on OpenG subject. Seriously, what's the joy of just rewriting the prototypes?.. I have studied those on my own, even though I have LV 2.5 distro for a while and do know, that some Occurrence functions are exposed there (in MANAGER.H, to be more precise). Moreover, those headers don't contain the entire interface. This is all, that is presented: /* Occurrence routines */ typedef Private *OccurHdlr; #define kNonOccurrence 0L #define kMaxInterval 0x7FFFFFFFL extern uInt32 gNextTimedOccurInterval; typedef void (*OHdlrProcPtr)(int32); Occurrence AllocOccur(void); int32 DeallocOccur(Occurrence o); OccurHdlr AllocOccurHdlr(Occurrence o, OHdlrProcPtr p, int32 param); int32 DeallocOccurHdlr(OccurHdlr oh); int32 Occur(Occurrence o); void OccurAtTime(Occurrence o, uInt32 t); int32 OnOccurrence(OccurHdlr oh, boolean noPrevious); int32 CancelOnOccur(OccurHdlr oh); boolean ChkOccurrences(void); boolean ChkTimerOccurrences(void); The headers lack OnOccurrenceWithTimeout and FireOccurHdlr and some others (likely, they seem to be non-existent in those early versions). Having said that, I admit that Occurrence API is not that complicated and is easily reversible for more or less experienced LV and asm programmers. -
Can Queues be accessed through CIN?
dadreamer replied to Taylorh140's topic in Calling External Code
Queues, Notifiers, DVRs and similar stuff, even when seems to be exposed from labview.exe in some form, is totally undocumented. Of course, you could try to RE those functions and if you're lucky enough, you could use few, maybe. But it will take a significant effort of you and won't become worth it at all. To synchronize your library with LabVIEW, you'd better try OS-native API (like Events, Mutexes, Semaphores or WaitableTimers on Windows) or some documented things like PostLVUserEvent or Occur of Occurrence API. To be honest, there are more Occurrence functions revealed, but they're undocumented as well, so use them at your own risk. What about CINs, I do recall that former Queues/Notifiers implementations were made on CINs entirely. I never had a chance to study their code, and not that I really wanted to. I suppose, they're not functional in modern LV versions anymore as they got replaced with better internal analogues. -
There's also LV Process pipes implementation (part of GOLPI project), which seems to work in 64-bit LabVIEW and is more or less updated. Honestly I've never given it a serious try and I recall some limitations of it comparing to the Rolf's library (e.g., the lack of stderr support AFAICR).
-
I think, you need to organize some kind of Inter-Process Communication (IPC) between the two. As long as both apps are made in LabVIEW, you have a wide variety of ways for them to communicate: TCP/IP, UDP, Network Streams, SV, Pipes, Shared Memory etc. I don't recommend the files-based IPC because it has some negative caveats like these. There's also an article on the other side: Inter-Application Communication (rather dated though).
-
You should use Use Default if Unwired property. I couldn't come quickly with a good example, you may take a look at this post for the start.
-
Maybe then you'd have more luck trying in PowerShell (if available). Also try without preceding .\ symbols. As I have Python paths written into the PATH environment variable, I don't even need to launch Python's own shell, I just execute that command in common Windows shell and it works.
-
Take a look at https://github.com/mefistotelis/pylabview You will need 3rd Python and Pillow package: After that you proceed as follows: Unpack the .exe into a separate directory (7-Zip unarchiver works fine for me). Take \.rsrc\RCDATA\2 file and put it near readRSRC.py. Run .\readRSRC.py -x -i ./2 in the command shell. Unpack 2_LVzp.bin to get your VIs. You may also find this thread interesting to read: EXE back to buildable project
-
Good work done! Another way would be to use MoveBlock function to read out the string data: How to determine string length when dereferencing string pointer using LabVIEW MoveBlock That way you could either read one byte at a time until you reach NULL byte or call StrLen, then allocate an U8 array of proper length and call MoveBlock finally. From what I can vaguely recall, GetValueByPointer XNode is not that fast as LabVIEW native internal functions (if that matters for you). Also I'm kind of unsure, whether you should deallocate that string, when you retrieved it in LabVIEW or the library deallocates it on its own (might be GC or some other technique used). Perhaps you could ask the developer about that or study the source codes. If you don't care, then just check for memory leaks, repeatedly retrieving a string (in a loop) and checking the memory taken by LabVIEW process.
-
I did a test like yours with For Loop and MoveBlock is a bit faster here. I'm getting 0,03 ms for RAS and 0,01 ms for MB. I took Initialize Array on MB diagram out of the Sequence, because it's just an extra operation. Also make sure you are not timing and filling the output indicator simultaneously, because the latter vastly impacts the measurements.
-
Only when I disable the wrapper generation on the CLFN, I see some small performance gain in MoveBlock against Replace Array Subset: So, in all other use-cases the native nodes do their job just fine and they're much simplier to use (and more safe also). That is just a PoC method to show, that the work with arrays could be done "traditional way" in LabVIEW too as in text-based languages. I even suppose, Replace Array Subset and In Place Element Structure were both optimised/tweaked in some ways to behave better even in a dumb memory copying.
-
Yeah, I guess it's obvious for (almost) every programmer. And well illustrated by the 4th method with MoveBlock call. Looking at that one might say, this is how the replace operation is made internally. By the way it's possible to speed up MoveBlock method a little disabling the wrapper generation. But still it is inferior in speed to the native methods (i.e., Replace Array Subset and In Place Element Structure).
-
Just pass a 8 bytes wide element as an union (U64 / double / 8 x U8 cluster) and treat it according to the type field after the function call. But I also see, that you have to pass a struct (i.e., a cluster), not a single union. So you should bundle order, type and label fields to your cluster as well. I don't see a definition of valueType and valueLabel items of the Value struct. Assume, they are enum (I32) and long (I32), is that correct? I'm also kind of unsure, who is responsible to set the return type (long, unsigned long, double or string) - the caller or the callee?.. If it's the caller and you want the return to be a string, you have to allocate the necessary amount of memory for char *s (DSNewPtr and friends) and deallocate it later. If it's the callee, then when you're getting the return as a string, you have to deallocate that string, when done with it.
-
You could try the VIs from here: FFMPEG scripting in LabVIEW (.NET). In FFMPEG Examples v1.1.zip archive you may find yuv420p to RGB.vi, that should do the work for you. Also take a look at yuvplayer, it might be helpful to verify that you're doing the conversion properly.
-
Massive performance difference between IDE and executable
dadreamer replied to Milox's topic in Machine Vision and Imaging
Well, seems like I had to say that LabVIEW also should behave as RTE does, but it does not for some obscure reason. So, my bad in phrasing there. It's not so easy to answer, not knowing how Vision internals work. I suppose, it has something to do with the way, how Vision's memory manager allocates memory. Perhaps it's more optimized to work in LabVIEW and less (or not) optimized for EXE's. I noticed that in IDE IMAQ Create takes nearly the same amount of time to run (0,03 to 0,06 ms), while in RTE that amount starts at 0,03 and raises on each iteration. Here are the shots to illustrate. IDE: RTE: Maybe someone from NI could elaborate on these differences?.. By the way, I found two more similar issues [1, 2] and the reason behind each one was not clarified. -
Massive performance difference between IDE and executable
dadreamer replied to Milox's topic in Machine Vision and Imaging
Same behaviour here on LabVIEW 2020 64-bit, but... Do you really need to create and store in memory 10 000 images at once? I'm even not surprised, that both LabVIEW and RTE go crazy trying to do that. When I take IMAQ Create out of the loops, the situation improves significantly. IDE: 0,1 s for the extracts, 0,4 s for the thresholding EXE: 0,2 s for the extracts, 0,4 s for the thresholding Of course, there's no any reason to divide the whole processing into two separate loops in this case (because you would get the same image slice on all 10 000 iterations. Instead there's a need to do the entire processing in one loop and finalize the image after the loop with IMAQ Dispose. With this approach you'd reuse the same memory location on each interation instead of making a new one. If you need to run the processing in several threads, just create N IMAQ images before the loop, do your things and dispose them, when all the work is done.