Jump to content

Rolf Kalbermatter

Members
  • Posts

    3,903
  • Joined

  • Last visited

  • Days Won

    269

Everything posted by Rolf Kalbermatter

  1. I thought, if the source code doesn't show these, we have to look into the binary. But there seems nowhere any reference to these three APIs. I've used the DLL Checker, a LabVIEW VI listing the import section of a DLL, Dependency Walker and even looked directly at the disassembly of the DLL, but I can find nowhere any reference to any of these three APIs. So which DLL are you looking at, the official 3.7.14 from the sqlite site? How do you determine that these APIs are required? Attached is the report produced by the LV 2010 DLL Checker for the latest sqlite3.dll from their site. Note that you will probably have to tackle the stubbed imports too, or at least check that there is no chance for the code to run through these code paths on an embedded system. sqllite3.report.txt
  2. Windows Taskbar handling

  3. I only understand chinese here. Sorry but what are you trying to do here??? An ASCII file that contains the source to an intensity graph? Typecasting Intensity Graph to a Image Display.ctl?? That are two entirely different types of data, the Intensity graph being a 2D array of numbers being displayed in a particular way, while the Image Display.ctl is the IMAQ control to display bitmap data. Typecasting only works for data that is interchangable from one format to the other without changing the memory content, but that is not a possibility between these two data types. Most likely what you want to do is to take your Intensity Display 2D data and display it in the IMAQ display in a similar way. But that requires a conversion, not a typecast. One possibility for this would be to use the IMAQ ArrayToImage.vi function from the IMAQ Toolkit. I would assume that you have that Toolkit installed if you have the Image Display.ctl in your palettes.
  4. Unless your system changed in the meantime. Windows Update anyone? A new driver installation? A harddisk cleanup or replacement? I mean a solution like that is probably ok for your specific private application, but definitely not an option for an NI supplied example, which is supposed to do the "right"TM thing.
  5. Well there is always possibility for disagreement with a certain implementation, and I'm not saying the way they are now is without real quirks, but graphs are indeed a very complicated beast. From early days when graphs had much less options (and property nodes were just a very limited possibility) one had to do sometimes rather adventurous things to get a certain feature visually. What I remember from there is that there are sometimes totally contradicting requirements for a certain operation. You couldn't implement one thing without sacrificing something else, and that was not only because of the limited control you had with property nodes and all, but often also a fundamental problem. On one side you do not want a popup menu with 300 options to select from, on the other hand you want it as flexible as possible without need to go into complicated property node voodoo. And I'm convinced there is no way to get those two requirements fulfilled. Also when adding a new option to a control like a graph, there will be always at least one corner case that needs yet again special handling, and with nowadays complicated graph quite likely a few dozen of them, and they are so easy to miss even with very involved testing and user involvement.
  6. I'm not sure what you are asking here. Do you want to know why NI didn't make a yellow node of this function? If that is your question I can think of a few reasons. It's much easier to add an "undocumented" VI in vi.lib calling back into LabVIEW than adding a new node to LabVIEW. A new node needs an icon, help and several more resources embedded in the executable. That is a lot of work in terms of extra work, testing and verifying. A VI is added easily to vi.lib, can be adapted, tested, modified and documented by non LabVIEW core developers, and if the need should arise and it didn't get documented in the meantime, changed, removed and whatever else. Adding a private export of a C function only requires the expertise of the LabVIEW core developer who works on that code, not the expertise of several people working on various parts of the whole LabVIEW core. A developer of a new tool in LabVIEW finding to need access to a specific internal data structure can either file a new proposal to add an (undocumented) node, and wait until the powers to be have decided that this is a good idea, developer resources have been assigned to work on that, and testing and documentation has had their say, or simply add that export to the exported LabVIEW functions, create a private VI to access it and be done. Sure such functionality might be an interesting candidate to turn into a node at some point, but chances are that nobody will look back once it's done and working. So it's a shortcut to add functionality to LabVIEW that a new tool might require, without having to go through a hole bunch of modifications of the LabVIEW core itself. Since the password protection is now seriously broken and can't be used to prevent people to go into such VIs to shoot their own foot, they probably will change policies in the future and move a lot more into the direction of new (possibly undocumented) nodes, to expose such functionality. Undocumented, because once a function has been documented it can't really be removed anymore or even just modified, without a lot of hassle.
  7. Believe me, you do not want to thinker with that. It's deep in the DCOM internas and after a few more hours debugging through disassembly even into the Windows interna I've figured it out. It was a combination of comctrl32 side-by-side assembly versioning and DCOM marshalling because of apartment threading limitations.caused by the fact that DCOM is still based on OLE and it's Windows 3.1 heritage. So I am now able to get some thumbbar buttons to draw and even return user events to LabVIEW. I'm going to do a little more cleanup and will then post the VI library. I think saying that this should be an IDE feature is a waaaaay to strong statement. It's a funny Windows gadget much like toolbar ribbons, but it's implementation has a few limitations and it's API is quite awkward. You wouldn't want to deal with the Taskbar API as is from a LabVIEW application as there are simply to many things you can do wrong to mess up for good. I'm trying to hide some of that complexity in the LabVIEW library I'm currently working on, but I'm not sure it will be possible to make it idiot proof, and as we all know engineers are even worse . Another point I have read on some blog about the Windows Taskbar excitement from many users applies here as well. You should NOT implement Windows taskbar functionality into your application, just because you can!! It's a decision that needs to be thought out seriously and implemented well, otherwise it is more annoying for the user than useful. The thumbbar specifically are only really useful for operations that do not require any activation of the application window in question. So what could this be used for in the LabVIEW project window? Starting a VI? Starting or stopping a compile build? Maybe the cancelation of a stop build but anything else needs more context such as which VI to start, or which of the potentially several target builds to start, etc, so it needs activation of the according window and context specific selection for the action and then the buttons make absolutely no sense. Clicking the thumbnail icon to activate the window and do whatever is needed to do is much more intuitive, than selecting a possibly obscure thumbbar button, that switches over to a dialog or the main VI in question to require the user to select in more detail what he wants to do. Attached is a first version of the library. Documentation is a little scarce at this stage, but it should be possible to figure out the most important functionality by looking at the two examples. And before anyone complains that the incuded DLL can't be loaded on his machine. This DLL was compiled using Visual C 2005 and requires therefore the MS C runtime library version 8.0.x. The attached vcruntime8.0.zip file contains both installers for the 32 bit and 64 bit versions of the MS C redistributable runtime libraries. Install whatever version your LabVIEW system has in order for the DLL to work. These installers are the most recent VC 8.0 runtime libraries officially available from Microsoft. lvtaskbar.zip vcruntime8.0.zip
  8. Well, out of curiosity I did spend a few hours on this. But it seems Windows is effectively denying every cooperation in making this functionality work from within LabVIEW. I can create a small Windows executable that uses the functions to assign an imagelist and the thumbbar definitions for the tumbbar buttons just fine, and I can use most of the other TaskBarList methods from within LabVIEW easily such as the Progress Bar functionality but any attempt to set the imagelist for the buttons from within LabVIEW fails with a very useless E_FAIL error message. Not sure what that would be really.
  9. Is it? And what did you learn from this awesome look behind the curtains? Yes there is a function you can use to translate an error code into an error string. But the VI that you looked at does that already for you without the need to bother about correct calling convention, parameter type setup and a few other nasty C details. Not sure I see the awesomeness here, other than the desire to feed your own curiosity and find more ways to shoot in your foot.
  10. What the name says: LabVIEW. Basically LabVIEW exports a lot of so called manager functions that can be called from C code, such as when you write a DLL (or shared library on non Windows systems). A lot of those manager functions are described in the External Code Reference Manual which comes as part of the help files in your LabVIEW installation. The LabVIEW library name is a special keyword, that tells the Call Library Node to link to whatever the current LabVIEW execution kernel is (LabVIEW.exe in the IDE, lvrt.dll in a built app). Note the case of the letters, which needs to match exactly with the official spelling. And before you ask, LabVIEW exports more functions than are described in the manual such as the one you found. Some are used internally by LabVIEW VIs but they are usually password protected. Sometimes one slips through the cracks. Most of those undocumented functions make no sense to be called outside of a very specific context, and some are rather harmful if not called in a very specific way. A lot of them are really only exported so that LabVIEW can itself use them as a sort callback and they make not really any sense to be called from a VI diagram.
  11. Congratulation. Perfect job!
  12. Well easy! But the hardest part of getting the SCC Provider Interface figured out is indeed done. Interfacing SVN through the command line interface isn't too complicated but I was at some point looking to integrate it completely as DLL and that is quite a different story. Since it also is a potential maintenance nightmare I abandoned that approach completely. SVN does normally guarantee backwards compatibility for the SVN command line interface, but no such guarantee exists for the binary API.
  13. If you follow that thread and go to the last post, you can see that Ton has actually already released both the provider as well as the API in the Code Repository. So you just need to download it and give it a testdrive.
  14. Daklu, I'm not trying to be difficult here but rather would like to understand how a LVOOP singleton would have much less dependency tree effect here. Yes Obtain and Release would be two different method VIs and the data dependency between these two would be through the LVOOP object wire instead of encapsulated in the single FGV. But that would decouple only the Obtain and Release operation as far as the hierarchy tree is concerned, not the fact that you use this object in various, possibly very loosely coupled clients. I say loosely coupled since they obviously have at least one common dependency, namely the protected resource in the singleton. And while easy extensibility is always nice to have, I'm not sure I see much possibility for that in such singleton objects. Would you care to elaborate on the dependency tree effect in this specific case and maybe also give an example of a desirable extension that would be much harder to add to the FGV than the LVOOP singleton?
  15. Well an FGV is the most trivial solution in terms of needing to code. It's not as explicit as a specific semaphore around everything and not as OOP as a true singleton class, but in terms of LabVIEW programming, something which is truely tried and proven. I would also think that it is probably the most performent solution, as the locking around non-reentrant VIs is a fully inherent operation of LabVIEW's execution scheduling and I doubt that explicit semaphore calls can be as quick as this. Also for me it is a natural choice since I use them often, even when the singleton functionality isn't an advantage but a liability, simply because I can whip them out in a short time, control everything I want and don't need to dig into how LVOOP does things. And reading about people complaints of unstable LabVIEW IDEs, when used with LVOOP doesn't exactly make me want to run for it either. I know this sounds like an excuse, but fact is that I have apparently trained myself to use LabVIEW in a way that exposes very little instability, unless I'm tinkering with DLLs, and especially self written DLLs during debug time, but that is something I can't possibly blame LabVIEW for.
  16. I believe LabVIEW used to do that too, when it was including the Great Cycle Smart Memory Heap Manager. Or were there two separate memory manager backends that LabVIEW could use? I'm not sure anymore and the details are fading, but fact is that LabVIEW had some intermediate memory manager layer on top of the OS memory manager that allowed it to not only debug memory usage on a more detailed level, but also consolidate many individual memory request by LabVIEW into much fewer and bigger ones for the OS. Great Circle was absorbed at some time and is of little significance nowadays other than for special, bad performing applications that get patched up by using Great Circle . Smartheap is apparently still on sale at http://www.microquill.com/. So it seems LabVIEW had at some point the option to replace the standard C Runtime memory manager functions with different backends, and was also shipped with them at some point. This supposedly helped to debug memory issues, and may still be used internally but could be an option to reduce the handle hunger from LabVIEW. So that LabVIEW is even by Mark Russinovich's standards a well behaving application .
  17. Well it's not invalid, but doesn't really do what you want directly. In order for the method to be executed on a VI you have to open a VI reference to it, so the entire VI hierarchy is already loaded and iterating through the list to open a VI reference to it does not really do anything useful anymore as the VI is already in memory. What you would have to do, is at built time, determine your hierarchy, sort that hierarchy in ascending order from lowest level VI to higher VI, possibly suppressing some of the lowest level VIs altogether and then save that information to a configuration file that your executable reads and starts doing the loading of the VIs from bottom up.After each Open VI Reference VI you would get more VI's loaded into memory and could use the percentage of already loaded VIs to the total amount of VIs for your progress bar. But executing your Get VI Hierarchy method node in your executable will cause the progress bar to stall while LabVIEW opens the Top level VI and then VERY quickly go through the Open VI References since it doesn't really need to do much anymore, but find the already loaded VI somewhere in memory.
  18. My natural instinct here would say, if you try to implement a singleton, which you apparently do, why not replace the queue with a Functional Global Variable VI that exposes Optain and Release methods? That also allows you to include any internal refcounting that you may require. The Obtain case creates your .Net object when the refcount is 0 and always increments the refcount, returning that .Net refnum and the Release case decrements the refcount and closes the .Net refnum when it reaches 0. Since everything from testing the refcount to acting on it accordingly happens inside the FGV, the problem on potential race conditions doesn't even exist. I'm sure this could be done with the singleton LVOOP pattern too, but functional global variables are ideal in LabVIEW to implement singletons. No need to do any semaphores or what else to avoid potential race conditions. A SEQ may seem great to implement a storage of a singleton object without having to do a separate VI, but if you need any kind of control over this objects lifetime, a FGV is the preferred choice since it allows implementing the lifetime management inside the FGV without the danger of creating race conditions.
  19. The most straight forward way to use them is to write C code, and for that you need a C compiler such as MS Visual Studio or LabWindows CVI. In a time long, long ago, this was used to create so called CINs but they are part of a long gone era, and the way nowadays is to create DLLs (shared libraries on non Windows platforms) and incorporate those shared libraries/DLLs into LabVIEW using the Call Library Node. In order for the C compiler to be able to find the declarations of those functions you have to #include "extcode.h" and possibly other include files from the <LabVIEW>/cintools directory. You also link the resulting code with labviewv.lib from the same directory so that the resulting DLL can be linked and later knows how to link to those manager functions in LabVIEW at runtime. Now if you need to call only very few of those manager functions, there is a little trick in that you define in the Call Library Node as library Name "LabVIEW" (without quotes and case does matter!!) and then you can configure the Call Library Node to match the definition of the manager function and LabVIEW will call into itself and execute that function. This is however an advanced feature. You do need to know how to configure the Call Library Node correctly, you need to be familiar with how LabVIEW stores its native data in memory, and should also be very savy about pointers and such in general. Also it is not very maintenance friendly since you have to fiddle in the LabVIEW diagram with C intrinsicaties and everytime you need to change something you have to go in there again and try to find out what you did last time. Editing a C file and creating a new DLL/shared library is in the long term so much easier, and once you end up calling more than a few C functions through the Call Library Node you really want to place the complicated C details in a C module and load that into LabVIEW through the Call Library Node, instead of making complicated push ups and more complicated fitness exercises on the LabVIEW diagram. What your problem is, I'm not sure, but if it is that you do not get the entire string since there seems to be NULL bytes already at the beginning, then you probably got Unicode16 strings. LabVIEW does NOT use Unicode strings at all internally but always uses the MBCS coding, and all LabVIEW manager string functions consequently operate on MBCS strings, so they can't deal with Unicode16 strings at all. In that case you better use Windows API functions that can work with WCHAR strings or alternatively have to convert the Unicode string into MBCS early on using the Windows API function WideCharToMultiByte().
  20. I didn't mean to indicate to call this function with the Call Library Node. While it would work for this one (and IID_PPV_ARGS() is just a casting macro to make sure the parameter passes to the function without compiling warning), the resulting ptbl is a pointer to a virtual table dispatch structure and that is a bit nasty to reference from a Call Library Node. However there is no way without invoking at least 3 or so methods from that virtual table to implement anything useful in terms of TaskBar App thumbs and friends. My only acceptable solution to this would be to write a little C code that is compiled into a DLL and then called from LabVIEW. This is also mandated in my opinion by the fact that any feedback from the Taskbar to the application is done through the Windows message queue. Hooking that, while possible with the LabVIEW Windows message queue library floating around, is a painful process, and much more cleanly done in the same C code DLL. As to creating your mentioned C header parser: Believe me you don't want to go there. I implemented such a beast for a project where I had to adapt to register definitions for a CAN device based on C type declarations in a database like structure. It "only" had to be able to identify the basic C types, structures and arrays and the typedefs made from them. And it already got a major task and one that, while it worked I didn't particularly feel confident about, to make some changes to it without breaking something else in it. Without an extensive unit test framework such a thing is already unmaintainable in any form. And while it theoretically also could parse function declarations that part never got tested at all, since it was not a requirement for the task at hand. And I'm sure there are still many C header nasties, that program can't parse properly. The C header parser used in the Import Library Wizard is most likely a bit further than the one I had written, but it also has it's limits and very specifically only maintains the information it requires to create the Call Library Node configuration for a particular function. This means that enum values are simply discarded, as the only information this library needs is the actual size of the enum, not its detailed definition. Same here. Add to this the fact that .Net is limiting yourself automatically to Windows only (no Mono is no solution as LabVIEW still lacks the .Net support on non-Windows platforms to even be theoretically able to call Mono. In practice it would almost surely fail even if it had such support.) This may seem like a moot point in this case with Windows shell integration, but I'm working regularly on other things where multi-platform support is not only an option but sometimes a requirement. And once you start to go down the C DLL path for such things you really don't feel like learning yet another programming environment like .Net, that is not only heavyweight and clunky but also limits yourself to a specific platform. I'm also sure that the frequent versioning of .Net is not just a coincidence but a strategy, to make following it getting a true challenge both for Mono as well as competing application development environments to MS Visual development offerings. By avoiding it whenever possible, I'm not limited by this strategy. From the little exposure to .Net so far I have to say it is very amazing how much they copied Java. Many libraries use the exact same naming only adapted to the .Net naming convention of using function names that start with an uppercase letter instead of a lowercase letter as Java uses. Almost feels like someone took the Java interfaces and put them through a tool to convert type names and function names to a different naming convention just for the sake of not being blamed for taking them verbatim.
  21. My first hunch before hearing about the password protected DB VIs was also the DB task. I know of some problems with result sets in the NI DB Toolkit. But as Shaun already said, I can't imagine it to be the NI DB Toolkit since that one is NOT password protected. And as far as I remember, the result set memory leak exists in the IDE too.
  22. [sarcasme] I recommend assembler for that! It has no restrictions in IDE enforced edit time delays, since it only needs the most simple text editor you can envision. Never mind the rest of the experience. {/sarcasme]
  23. I came across another way of slow down a few years back. I inherited a machine control application that consisted of one main VI going over 10MB size, and a whole bunch of subVIs doing stupidly little. The main VI consisted of several stacked sequence structures with up to 100 frames and almost every frame contained a case structure that was only enabled based on a global string that contained in fact the next state to execute. Basically it was a state machine with the sequence frames consisting a grouping of states and to get to one particular stage LabVIEW had to run through each sequence frame, most of them doing nothing since the case structure inside did not react on the current state. Talk about a state machine turned inside out and upside down and then again some. Selecting a wire, node or subVI in that diagram was slooooooooooow, as each of these actions caused a several seconds delay. Moving a node was equally slow as each move caused a similar delay. It was a total pain to do anything on that application and it needed work as it had several bugs. I invested several days restructuring the architecture into a real state machine design and placing several logical sub state-machines into their own subVI, also removing about 99% of the several 1000 globals and once I had done that, the whole editing got snappy again. The main VI had been reduced to about 1MB and the different sub statemachine VIs together took mabye another 4MB of disk space. Replacing all the globals with a few shift registers had slashed the disk print of the VIs almost to half. I did make the driver VIs a bit smarter by moving some of the logic into them instead of copying the same operation repeatedly in the main VI but getting rid of the enormous number of sequence frames as well as the many globals that were mostly only a workaround for the not existing shift registers did both get the disk size down a lot as well as make the editing again a useful operation instead of being simply an annoyance. Surprisingly enough the runtime performance of the original application wasn't really bad, but the redesigned system hardly got ever over 5% CPU usage even when it was busy controlling all the serial devices and motion systems. How the original programmer ever was able to finish his system with such an architecture and the horrible edit delays for almost every single mouse move I can't imagine. It for sure wasn't a LabVIEW programmer and I later learned that he had only done Visual Basic applications before.
  24. From what I read on MDSN it is fairly easy to do that from C/C++. You just want to use the ITaskBar3 interface in shobjidl.h. A single call to // Create an instance of ITaskbarList3 ITaskBarList3 *ptbl; HRESULT hr = CoCreateInstance(CLSID_TaskbarList, NULL, CLSCTX_INPROC_SERVER, IID_PPV_ARGS(&ptbl); [/CODE] And then you can call the relevant methods of the ITaskBarList3 COM object. This even works from pure C. [CODE] if (SUCCEEDED(hr)) { // Declare the image list that contains the button images. hr = ptbl->ThumbBarSetImageList(hwnd, himl); if (SUCCEEDED(hr)) { // Attach the toolbar to the thumbnail hr = ptbl->ThumbBarAddButtons(hwnd, ARRAYSIZE(thbButtons), &thbButtons); } ptbl->Release(); } return hr; [/CODE] However handling of events happens through Windows messages, so you have to hook the Windows message queue in LabVIEW and this is were things always get a bit hairy with Windows shell integration in LabVIEW. Same about ShellNotify and other such things. Same here! A fun project to do but with very little real world benefit for the type of application we generally do in LabVIEW.
  25. Let's see. I'm by no means a Java crack and am not sure I ever will be. My interest with Java was only started when I wanted to do some stuff under Android, mostly for fun so far. Incidentally looking at the Java scene I think the flair of the days when Sun was yielding the scepter has mostly gone. Oracle seems to be seen by many as an unfriendly king and by some even as a hostile tyrant. Google sort of took over a bit but tries to keep a low profile in terms of Java. They just use the idea but don't really promote it at all, probably also because of the law suits. I think Oracle has done the single most effective move to kill Java as an idea with their recent actions. But lets get back at your question: There is the java.util.queue interface with it's many incarnations like AbstractQueue, ArrayBlockingQueue, ConcurrentLinkedQueue, DelayQueue, LinkedBlockingQueue, LinkedList, PriorityBlockingQueue, PriorityQueue, SynchronousQueue. Then we have the inherent synchonous(obj) { } keyword that can be used on any object to create blocks around code that needs to be protected. Only a single block of code can be at any time inside a synchronous block for a specific object. And last but not least there is the notify() and wait() method the java object class implements which every other Java object is derived from directly or through other object classes. These two methods are a bit special since they do actually work together with the synchronous(obj) keyword. I haven't mastered this part yet fully but I had trouble to use those methods unless the code block in which they are called is protected with the synchonous(obj) keyword but reading suggests that this should not always be necessary. You probably have a point there. All I can say to that is that it seems cleaner to me to have a specific object interface be able to manage it's thread needs on its own by using the appropriate thread policy such as a threadpool with whatever limits seems useful, and let the proven OS implementation handle the distribution of the threads on whatever cores are available. It probably won't speed up things at all to do so, but I just like to have the idea of being in control if I feel the need is there. On the other hand, I have not to complain about how LabVIEW handles concurrent parallel execution so far. It seems just as capable to handle multiple code parts that can operate in parallel with the available CPU power as a Java program that uses several threads. So in the end there may be nothing really left but the feeling of having more control over the things, which is also sometimes a reason for me to implement certain things in C and incorporate them into LabVIEW as shared library. And because of that you respond to it!? I probably will try to take a look at your project. Always interesting to see new things, eventhough I'm not sure I will groke the whole picture.
×
×
  • Create New...

Important Information

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