Jump to content

Rolf Kalbermatter

Members
  • Posts

    3,786
  • Joined

  • Last visited

  • Days Won

    245

Everything posted by Rolf Kalbermatter

  1. QUOTE(RONIN10 @ Dec 7 2007, 04:34 PM) I had my local NI rep and another NI guy visiting from TX sit down with me and take a look at this together. It was beyond their certainty as to what was wrong, but they seemed to key in on the void pointer as being the likely culprit and (unfortunately) didn't have a solution in mind. So when I go to run this, the node execute succesfully in that I get a zero return value (specified in the source code as successful completion of the function), but the I32 I'm wiring to the void pointer doesn't get populated with information I'm requesting (number of parameters in teh data stream, in this case). It also causes an Error 15 code in LabVIEW and crashes the whole application after hanging for a few seconds. Any suggestions of ways to correct this and why it is behaving as it is? Thanks in advance! There are two things that could be wrong: datastream_t is not a standard C type so I'm not sure if treating it as an int32 is ok. If it is just a handle you get from some open function then it should be ok. The void pointer quite likely is the culprit here. Unfortunately C is not a language that describes parameters in itself sufficiently in terms of the exact meaning and context of their use. void pointers are especially bad in that respect as they can be really anything you can think of. What it is can only be decided by knowing the exact context of that function, which you didn't give in any way. It could be a byte buffer in which the function is supposed to write the data from the stream. In that case the caller (your LabVIEW diagram) needs to allocate that buffer. As the function has no parameter to tell the size of that buffer and therefore you would need to know that size before calling that function I can only think of a few possibilities: - The function works with a fixed size buffer always. - You can pass in a NULL pointer and get the needed size as return value of the func'tion to allocate that buffer and call the same function again. - There is another function that can tell you what size is required. These things can not be deducted from the function prototype you show but only from the source code, a possible code example or the function description in some programmer manual to the library. Another possibility is that the function allocates the buffer itself and returns a pointer to it in the void parameter. In that case you would need the exact structure of that buffer and hope it is a flat buffer. Retrieving non flat data (pointers inside that buffer) in such a way is a mature pain and for me ALWAYS a reason to write a wrapper DLL or in your case since you have the DLL source code an additional more LabVIEW friendly exported function. Also since the DLL allocated the buffer it should provide you with a function to deallocate it later on after you don't need it anymore as otherwise you are creating memory leaks. All in all there is way to little information available to tell you what exactly goes wrong and even less to give you detailed ideas about how to do it correctly. And that is not LabVIEWs fault but the nature of C which does not fully document the parameter datatypes of functions in general und the exact usage context in special. Rolf Kalbermatter
  2. QUOTE(gammalight @ Dec 6 2007, 10:14 PM) Probably recompiling the low level support library of the Report Generation Toolkit for Office 2007 and installing that with your application instead of the default 2003 version would solve that issue. So MS most probably did it again and changed the ActiveX interface between Office versions enough, that LabVIEW gets trouble running it withoug recomiling its VIs. Rolf Kalbermatter
  3. QUOTE(Vladimir Drzik @ Dec 6 2007, 06:33 AM) I was attending a presentation during the LV days all over the world that followed the NI week. The presenter, an active LabVIEW developer much into especially these areas of LabVIEW, only said that the number of executions systems was now more dynamical depending on the actual number of cores LabVIEW could find. He didn't say specific numbers because I think that is hard to do anyhow. There is most probably some heuristics involved that use to some point somewhat arbitrarily chosen values, with lots of tweaking, testing and such during the devlopment. And those heuristics will likely change again as different multi-core designs get available, different CPU architectures are introduced and different OS support is introduced. One possible starting point is above mentioned VI. It should give you an idea about what the currently used setup is for any particular machine. Interestingly on my system, an Intel Dual core machine it reports 4 CPUs Rolf Kalbermatter
  4. QUOTE(gustav @ Dec 5 2007, 12:43 PM) The timed loop apparently calls into external DLLs. Somehow and somewhere that external code does not properly get informed about the shutdown so the process hangs on the exit callback of that external DLL, most probably. I haven't used the timed loop very much but I think this is one thing that has happened to me too in the past, including in the development environment. Asynchronous external code is tricky in LabVIEW, even for the creators of LabVIEW :-) Rolf Kalbermatter
  5. QUOTE(Vladimir Drzik @ Dec 4 2007, 03:25 AM) Well the number of threads per execution system is a not so interesting detail, IMHO. LabVIEW initialy used as default 1 I think then increased to 2 and then 4 but in 8.5 this is actually more dynamic based on the number of CPU cores LabVIEW can find in the system. Even before that this number was not set in stone but could be user configured with a somewhat hidden VI in vi.lib/Utility/sysinfo.llb/threadConfig.vi. That configuration is written into the LabVIEW ini file and in such a way can be transfered to a built application too. Rolf Kalbermatter
  6. QUOTE(prayami @ Dec 3 2007, 07:32 PM) Then you would have to look at the http://www.ni.com/embedded/' target="_blank">LabVIEW for Embedded Edition version, but that is not cheap. And you will have to have to add support for your hardware target to this LabVIEW version to integrate the GNU toolchain or whatever other C toolchain you will use to write software for your controller board. This integration work should not be underestimated. Provided you have someone with a good familiarity with both your toolchain and LabVIEW its still several weeks of work before it will work just right. QUOTE Can we have Real Time Operating System on our microcontroller and can we run LabVIEW web server inside that( i.e. I mean Embedded Web Server )? Yes but not through LabVIEW. You will have to provide your own realtime OS solution such as VxWorks, Pharlap or whatever you can find for your CPU target and then integrate its toolchain into LabVIEW Embedded by writing some support VIs and such. The LabVIEW embedded Web Server is part of the LabVIEW kernel in the Development Module/runtime system and will not be transfered to an external embedded target at all. QUOTE On this server root there will be VIs & html files which will call those VIs. Is this possible? As per your answer it is not possible to have LabVIEW web server without the PC? An embedded application is really LabVIEW code translated into C and then compiled through the target specific toolchain including its C compiler. As such it comes from LabVIEW code but does not know how to load and execute native LabVIEW VIs at all. There will be no way to make your embedded target to load and run LabVIEW VIs. The only way to do that is by creating a target platform that is able to run one of the standard supported LabVIEW platforms such as Win32/x86 or Linux/x86. On such a platform you can simply install a full LabVIEW runtime system that is able to load and execute LabVIEW VIs natively. Or you buy a NI hardware platform with integrated OS such as Compact Fieldpoint or such. NI ported their LabVIEW kernel to run on those systems so they can load an run VIs directly. You can't do that yourself since you would need the LabVIEW source code for that (and LabVIEW itself does as far as I know not directly support ARM at least officially, so that would be out of question). And no, the PDA versions of LabVIEW really do more something like what LabVIEW Embedded is doing by invoking the Visual C compiler for creating executables for the ARM based PDA devices. I'm not aware of any ARM based LabVIEW version sold, that could execute LabVIEW VIs directly, eventhough there probably is rudimentary support in the LabVIEW source code for ARM as indicated in the cintools headers, but I would guess that it is not really substantial and even if it would, it is most likely not very well tested (since only features that get actively used get enough test exposure to make sure they work at least halfway decently). Rolf Kalbermatter
  7. QUOTE(ned @ Nov 20 2007, 03:17 PM) Another reason (except the N=0 issue which I think was changed at some point around 7.x) is that wiring the refnum out of the loop defaults to autoindexing for the for loop which is almost never what it should do. Using shift registers solves that too. Rolf Kalbermatter
  8. QUOTE(0815Jack @ Nov 29 2007, 05:41 AM) Do you know anything about C programming? If so you should be set fairly well and reading a bit in the External Code Reference Manual in the LabVIEW online help should get you enough to get started. Without at least some basic C programming knowledge you will be in for a good and most possibly steep learning experience before it does not crash anymore. And I just see that they export a C++ API. The Call Library Node can not call that directly. It can only access standard C exported functions, no C++ object interfaces. So you will have to create a wrapper DLL, wrapping the C++ method calls into standard C exported functions. All in all it does not seem to me to be a good project to start into the depths of the Call Library Node and C programming. Possibly the ActiveX wrapper or maybe the Visual Basic 5 and 6 example could help a bit. The ActiveX wrapper would allow you to access the Media Library through LabVIEWs ActiveX interface which would mean you do not have to directly deal with C datatypes, memory allocation issues and all such difficulties. Rolf Kalbermatter
  9. QUOTE(hviewlabs @ Nov 28 2007, 03:27 PM) You can try to get NI to give you this for certain functionality under an NDA. Changes that you will get it are however very close to 0%. Reasons you could get that information basically boil down to this: 1) Show NI that they can sell several hundred extra LabVIEW licenses if they give you that information or that they will get a multi million hardware sale. Reasons why they don't want to do this: 1) Many of those APIs do nothing useful for any possible client other than LabVIEW itself. 2) Many depend on other functionality not exported directly at all. 3) Every documented API needs to remain fixed for the rest of LabVIEW's lifetime to avoid breaking existing apps outside of NI's control. 4) Some of the APIs could reveal sensitive information if fully documented. So go and figure your chances. QUOTE(Tomi Maila @ Nov 28 2007, 04:26 PM) Oh. I thought it will only work in all supported platforms but not in a build app unless you used labview runtime instead of the executable. Well I guess Rolf is right here. He's such a guru in these things There is no difference between using the runtime and a LabVIEW executable since about LabVIEW 4.0 or so. Before that a LabVIEW executable was self contained, with the entire LabVIEW runtime embedded in the executable itself. Since then every LabVIEW executable will always refer to lvrt.dll whenever wanting to do any LabVIEW specific operation. And yes using LabVIEW (case very important) instead of LaBvIeW.exe should since about LabVIEW 6.0 also work in an excutable/runtime environment. The Call Library Node contains specific code detecting that keyword and directly rediricting to whatever kernel is doing the LabVIEW nitty gritty work at that moment. (lvrt.dll or labview.exe) QUOTE(Tomi Maila @ Nov 23 2007, 12:08 PM) Hi,Have you ever wanted to know what's the pointer to a LabVIEW buffer? Well in LabVIEW 8.5 you can actually find it out. LabVIEW 8.5 supports calling a shared library with constant arguments. As the arguments passed to the shared library are considered constant, LabVIEW reuses an existing data buffer for the shared library call. It doesn't make a copy of the data to pass the copy to the shared library instead of the original data. This allows reading and modifying wires parallel to the shared library. If these wires share buffer with a constant, then the value of the constant can be read modified as well.So what's the trick? Well, to understand the trick we first need to understand how LabVIEW data is stored into memory. LabVIEW uses two kind of memory models for data. For fixed sized data such as numeric types, booleans, clusters and references LabVIEW users pointers to the data to pass the data around. Each buffer is therefore referenced with a pointer to the data. For variable sized data such as strings and arrays and apparently also LabVIEW classes, LabVIEW uses handles (pointers to pointers) to the data. I think this is enough of introduction. I don't want to spoil all the fun. Take a look by yourself how to find out the pointer to fixed sized buffers and the handle to variable sized buffers. http://lavag.org/old_files/monthly_11_2007/post-4014-1195837700.png' target="_blank"> A correctly configured MoveBlock call can do the same as your GetValueByPointer since LabVIEW 5.x already. Rolf Kalbermatter
  10. QUOTE(TobyD @ Nov 28 2007, 02:59 PM) Could it be that your DLL calls indirectly other DLLs that are in the same directory? When LabVIEW asks Windows to load a library at a specific path Windows does attempt to load it, and when that library references other libraries it tries to load them too. If one of those referenced library loads fails the entire load fails and Windows tells LabVIEW: sorry! Now Windows will search for libraries in following order: 1) a library with the same name is already mapped in the process space 2) inside the directory where the executable for the current process is located (here the directory where LabVIEW.exe is) 3) in the System directory 4) in the Windows directory 5) in any directory mentioned in the current PATH environment variable and most possibly also in the "current directory". The current directory is a process specific global variable that gets manipulated by various Windows APIs. One of them is also the API that LabVIEW uses to display the System File Dialog. So if you browse to your DLL directory to tell LabVIEW which DLL to load and that DLL references other DLLs implicitedly that are in the same directory, Windows suddenly will find them, but not before. Solution would be either to move those DLLs all into a location that is properly searched by Windows, or add the location of that directory to the PATH environment variable. Rolf Kalbermatter
  11. QUOTE(hviewlabs @ Nov 21 2007, 12:19 PM) That node has an input that accepts just about any LabVIEW type including a cluster. For non-cluster types the packtype has no meaning. But for cluster types the node will align the individual elements to that packing alignment. This is also where the node is actually a bit complicated I'm sure. The extraction of linear arrays or skalars is a no brainer really. The fact that an xnode apperently can have an input parameter that can truely adapt to just about any LabVIEW datatype would be the most interesting aspect of that node, but according to NI there is no such thing like an Xnode and therefore no self adapting datatype input. QUOTE(Godpheray @ Nov 26 2007, 09:48 PM) GetValueByPointer takes the C style pointer and the corresponding data type, which are generated by Import Shared Library Tool, as inputs and copies the value which the pointer points in shared library(dll/so/framework) to LabVIEW.Input terminals:Input Type: Input type is the LabVIEW data type to which you want to pass into LabVIEW. Input type can be Numeric, string, Array, Cluster . This VI returns an error if LabVIEW cannot convert the data wired to Pointer to the data type you wire to this input. If the data is integer, you can coerce the data to another numeric representation, such as an extended-precision, floating-point number.Pointer: Pointer is a memory address represented by a 32-bit unsigned integer in LabVIEW. Pack Type: Byte alignment information of the Input Type. Output terminals:Value:Value is the data copied from the memory which is pointed by Pointer and changed to the data type specified by Input type. One interesting aspect of that node seems to be the fact that one can convert a pointer into a string or array. I can see that converting into a string should be possible when simply looking for the NULL termination character, but turning it in an array would suggest to me that the input pointer can not just be any possible pointer but must be one prepared by DSNewPtr.vi. Otherwise that node has no way of knowing how big the memory area the pointer is pointing too could possibly be. There is not even a documented DSPtrSize function, so I guess DSNewPtr.vi must do some internal magic to the pointer so that GetValueByPointer.xnode can make sure to never overrun the end of the allocated memory area. Rolf Kalbermatter
  12. QUOTE(CraigGraham @ Nov 26 2007, 08:58 AM) There are two ways for doing this. One is with a simple FTP client uploading the file to the cFP replacing the original one. I haven't used that yet. Another one is to use the http://zone.ni.com/devzone/cda/tut/p/id/3937' target="_blank">RT System Replication VI library available on NIs site. With that you can build a LabVIEW app to install, control, and upload new RT exe files on the target. In one case recently I simply built that library into the system configuration for the host application. User simply puts a new exe in a special directory on the host, goes in there presses "update remote system", et voila. Rolf Kalbermatter
  13. QUOTE(Mike C @ Nov 27 2007, 09:22 AM) If you want to use the internet toolkit you certainly can go into the VI library and modify it in such a way to provide somehow some information in a global variable about the current size. The internet toolkit FTP VIs if you dig into them, does basically read multiple blocks inside a loop writing them to the desired file, until all data has been retrieved or the connection is aborted. There is no current progress information because the high level VI to download a file is written in such a way to only return on a finished download or on error. So there would be never a meaningful progress return value from that VI itself. The information you want to know is deeper inside that VI hierarchy and you will have to modify those VIs somewhat to give you that information in a meaningful way. Rolf Kalbermatter
  14. QUOTE(Jim Kring @ Nov 27 2007, 01:09 AM) According to the C++ example on MSDN it would seem that the EncoderParameter.value should be an Int64. So I simply tried to select the EncoderParameter(Encoder encoder, Int64 value) method instead of the EncoderParameter(Encoder encoder, Int16 value) and everything seems to be alright. At least I do not get any error anymore. Of course the Convert to Int16 could go away or be explicitedly converted to Int64 but LabVIEW will do that implicitedly too. Rolf Kalbermatter
  15. QUOTE(tumanovalex @ Nov 23 2007, 01:58 PM) Well, you obviously need to read a C text book about data pointers. The way you try to return the data pointer simply can't work. Allocating the buffer inside the function and assigning it to the array pointer does absolutely nothing in terms of allowing the caller to ever see that buffer. You would need a reference to an array pointer and not just an array pointer alone but because of memory management it is a very bad idea in general (and especially bad for use in LabVIEW) to allocate a memory buffer inside a function and return that to the caller. The way this is normally handled is by providing a possibility to either of the two possibilities: 1) Provide a way to retireve the necessary buffer size first, allocating the buffer in the caller (here LabVIEW) and then retrive the actual data. You could do this by providing first a NULL pointer as buffer parameter and in that case only return the file size. Then calculate the necessary buffer size in LabVIEW allocate that buffer as an array of the elements you require (double) and pass that a C array data pointer this time. 2) Allocate a reasonably sized buffer in LabVIEW first, pass the size of it together with the buffer itself to the function and then inside the function check if the size is big enough. If it is read the data into the buffer, returning the actual size filled in and return a success indication as function return value. If it is to small, return the actually needed size together with an error indication that the buffer was to small and then in LabVIEW reallocate the buffer with the necessary size and call the function again with the resized buffer. These two methods are not only the standard method for just about any C library but also the only reasonably compatible ones that will allow your code to be called from many different environments including LabVIEW. Rolf Kalbermatter
  16. QUOTE(hviewlabs @ Nov 20 2007, 09:03 PM) Try to use the library import wizard in 8.5. It can do some of these things for not to complicated structures, but if that does not work those functions won't help you magically. You will have to understand at least as much about C and pointers in C as you would need to write your own wrapper DLL in C to deal with that in a more clean and much easier to maintain manner. Rolf Kalbermatter
  17. QUOTE(hviewlabs @ Nov 20 2007, 09:03 PM) Try to use the library import wizard in 8.5. It can do some of these things for not to complicated structures, but if that does not work those functions won't help you magically. You will have to understand at least as much about C and pointers in C as you would need to write your own wrapper DLL in C to deal with that in a more clean and much easier to maintain manner. Rolf Kalbermatter
  18. QUOTE(hviewlabs @ Nov 20 2007, 08:14 PM) Those VIs were not designed (yet) for general use but are used by the Library Import Wizard in 8.5 which should support functions parameters to structures containing variable sized data. All the functions except the xnode are really just wrappers around LabVIEW memory manager functions. What is done through the library import wizard has been of course possible in LabVIEW since about 5.x and I did use it myself a few times but I went with purpose never into the details about how this has to be done, because of several reasons. - It is very complicated and even when explained step by step I would not expect anyone without a very good C knowledge to be able to understand. - Those that can understand this can also do it themselves. - The necessary work is tedious to do, complicated, error prone and oh well, throw in whatever you do not like about programming ;-) - For anything but a very simple case with one or two functions with a parameter with one or two pointers in it at most, it is a LOT more work than writing a wrapper DLL and it is a complete pain in the ###### to maintain. As to your question about PackType, I could imagine it could have something to do with memory alignement of structure elements. As such it would be a number that would be 1, 2, 4, 8, or 16. As to passing around references inside LabVIEW: You only can do that when you represent that reference as a pointer (i.e. int32/64) but not as a native variable sized LabVIEW datatype. Dataflow simply mandates that memory objects that can be resized get copied at wire branches, unless the LabVIEW compiler can optimize them in such a way that branches that consume the wire only fo reading without reuseing them are executed first. Doing an advanced optimizer that could go around that across structure boundaries might be theoretical possible, although I don't think it is currently done, but a macro optimizer that could deal with this task across (possibly dynamically related) subVI boundaries would be most probably a o^n problem or worse. Rolf Kalbermatter
  19. QUOTE(Yen @ Nov 13 2007, 12:32 PM) Making the Library path in the configuration read LabVIEW instead of LabVIEW.exe would help immensely to make this VI run on any LabVIEW platform And I have a somewhat more useful version of this I think.CTRL Size Front Panel Object.vi QUOTE(Norm Kirchner @ Nov 13 2007, 04:10 PM) Actually, NI beat you to it. I have to say that I'm flabbergasted that NI has had this available and never wrapped it up for us, nor have I seen anyone else wrap it up.Is it dangerous to use? It's used deep in some of the tools that LabVIEW comes with since quite some versions that are really just LabVIEW VIs too. I haven't found it to be dangerous and it does actually have some very nice features such as resizing list boxes even vertically on pixel level, something you couldn't do in LabVIEW 7.x with other properties (the only way that allowed resizing the height of list boxes was through number of lines and calculating that based on pixel size changes of the window was a pain in the a__. Some of my application use this to create a real autosizing of some of the UIs when the user resizes the window. Rolf Kalbermatter
  20. QUOTE(Norm Kirchner @ Nov 6 2007, 05:44 PM) Why not add a glyph to the column headers too and while we are at that support some standard build in sorting or better yet a plugin for a comparison routine that is used for sorting when clicking on a column header. Rolf Kalbermatter
  21. QUOTE(TiT @ Nov 8 2007, 03:15 AM) Hmm, does that pertain to your own perceived coding style somehow? I'm sure you are doing much better than that! Rolf Kalbermatter
  22. QUOTE(Yen @ Oct 21 2007, 04:01 PM) Actually the OpenG Builder and also the OpenG Commander (and quite likely VIPM as it uses for quite some part still the same VI libraries) does have VIs supporting symbolic paths. I created them back in the early days of OpenG Builder together with the lvzip library to support a flexible package installation system, that the ogp files are still mostly based upon. For the Commander they reside in OGPM PATH Convert Keyword.vi, OGPM PATH Keyword Expand.vi and OGPM Keyword Manager.vi.QUOTE(Aristos Queue @ Oct 21 2007, 08:31 AM) I won't get involved with the discussion about more symbolic paths to LV built-in stuff. Technical pros, technical cons, politics, blah, blah, blah...But as far as user-defined paths are concerned, there's a number of technical blocks to with having arbitrary definitions for symbolic paths as they're used on the internals of LV. But I could see someone creating a set of VIs that managed a path translation scheme for loading VIs dynamically from user-defined symbolic paths. Might be useful for one of you to put together. Only problem with that is that it would not pertain to the paths stored in VIs itself and to loading them as that requires access to LabVIEW interna that can not be dealt with with "App:Read/Write Linker Info from File" afaik. Rolf Kalbermatter
  23. QUOTE(Jim Kring @ Nov 5 2007, 04:37 PM) That was my first guess starting to read this thread and I'm pretty sure you hit the nail on the head. The Dependancies scan in the project is almost certainly using the "Linker:Read Info From File" but probably only when loading a VI. This function is very fast in returning all relevant dependancies including CINs, external code libraries and such so it makes sense to use it instead of trying to do something in LabVIEW itself which would be WAAAAAY slower. I'm not sure it makes sense to show the CIN as a dependancy as it is really already embedded in the relevant VI and as such there is no physical file on disk that could be mapped to this item. So probably the filtering of the items should have taken out CINs or otherwise it should at least use a different icon. Rolf Kalbermatter
  24. QUOTE(silmaril @ Oct 23 2007, 03:53 AM) I can't support the original complain either, printing front panels quite often both to real printers as also to redirected PDF file printer drivers. But yes making sure that the front panel is drawn before you invoke the print operation is very important ;-). There are actually many ways to cause this, such as using an explicit Print Panel To Printer.vi I got from the NI site as well as print on completion of a VI, but I think I haven't used the later in quite some time. Also making sure the front panel is visible during printing might make a difference too, depending on the display driver. In that case decreasing the display speed optimization often can make it work even with hidden front panel. And if these things won't help (quite unlikely and probably the reason why this hasn't been adressed yet as the OP thinks, as addressing bugs that are hard to reproduce or are really more an operator error is something most developers react with a "Not a bug" label), changing the printing method could make a difference too. bitmap, Postscript, greyscale as well as changing printer drivers could actually give more information as to what could be wrong. Not all printer drivers work well in all print modes and that is quite often more a bug in the printer driver than in LabVIEW. Rolf Kalbermatter
  25. QUOTE(yogi reddy @ Nov 19 2007, 11:22 AM) Then your sender side is wrong somehow. From what I can see you are trying to send a 2D array of a size I'm way to lazy to find out by parsing the Matlab script, every 10 ms to each connected client. If this array is anything bigger than a few elements by a few elements you happily can throw data at the winsock library that has to exhaust your memory sooner or later. Why you try to send the same data over and over again with 10ms interval to each client is really beyond me. Just send it once when a new connection arrives and then close the connection for now. Also your error handling is sub par by far. Not adding the connection refnum back into your array after an eror is a good idea, but that doesn't mean that the refnum hadn't been valid and shouldn't at least be attempted to get closed. Otherwise you leak memory with every new refnum that gets thrown out of the bath due to some communication error on that refnum. Rolf Kalbermatter
×
×
  • Create New...

Important Information

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