Jump to content

Rolf Kalbermatter

Members
  • Posts

    3,871
  • Joined

  • Last visited

  • Days Won

    262

Everything posted by Rolf Kalbermatter

  1. And where in this is your: void myfunction(double ***arrayptrs, int *size) If this would be your allocateArrays() then what you would do is make sure to export free_arrayptrs() too and call that from LabVIEW at the end. Also *arrayptrs_out = (double**)malloc(*arraycnt_out*sizeof(double*)); should probably be instead: *arrayptrs_out = (double**)malloc(*size * sizeof(double*)); Then in LabVIEW you configure the parameter as pointer sized integer passed by reference, then in a loop do what ned has suggested before. But your proposed interface is pretty weak. While you return the number of array pointers in the returned data in *size, the caller has absolutely no way to know how many elements of data each array contains. This would be just by convention (caller and callee both have to know magically) and that is always a very bad API design. And you forgot to deallocate the array of array pointers in your free_arrayptrs()!!!!
  2. The TLB file is now embedded in the LabVIEW executable. Everything else works the same.
  3. It could be that the function allocates the array of arrays itself and returns it and for that the pointer of pointer needs to be passed by reference. But there is absolutely no way to tell from the C prototype. The C syntax alone is notoriously inadequate to describe such details. The only way to know is to read the function documentation, consult any possible C sample that comes with the library and usually do lots of trial and error anyways since even the documentation and samples are usually to poorly made than that they would explain everything. Basically the solution to free() the array in the calling program is not safe because of the possible mismatch of the C runtime library between what the DLL uses and what the caller uses. The library exposing functions that return allocated memory MUST always export a function to deallocate that memory properly.
  4. No DSDisposePtr() is not safe! Your DLL should export a function that uses internally free() to dispose those resources. One of the reason for this is that the DLL will most likely link to a different C runtime library than what LabVIEW would use, so that malloc() in the DLL works on a different managed heap than free() in LabVIEW. Also DSDisposePtr() does a little more than just calling free() and that would conflict with a memory pointer only allocated with malloc() even if the free() used by LabVIEW would operate on the same heap than the malloc() used in your DLL.
  5. Well as has been many times stated by me and many others about interfacing external code there is a fundamental and very important difference about having a string that is fixed size or variable size. Fixed size looks like this: type name[n]; and when used in a struct is fully inlined. This means that the struct is extended directly with n elements of type. This however: type *name; will only place a pointer in the structure and will require the program(mer) to manage the actual memory himself. Now a LabVIEW string is again a different beast that is not directly compatible with either C declaration, so adding a LabVIEW String to the cluster is really the totally wrong thing here. If it was a pointer you would have to add an integer in there (32 bit if you intend to run it in LabVIEW 32 bit, and 64 bit if you intend to run it in LabVIEW 64 bit). Since it is inlined you have to place a cluster in there with 256 U8 elements. Not nice but that is how this is to be solved.
  6. The OpenG LabVIEW Data Toolkit's origine date from LabVIEW 5 or so times when waveforms, timestamps etc. were not yet present. Some of that was added later by whoever found to need that particular datatype support, but usually not in a structured manner either but just in the particular functions that happened to be used by that person and sometimes only to the limited extend that was required by him or her. I don't think there is any other reason to the lack of full support for the datatypes that you noticed, other than that they didn't exist back then or that the original developer decided that they were unneeded or to cumbersome to implement for the moment. You usually have to cut a line somewhere when developing such a large and involved library as this. If you start with the intention to support everything and all and handle every corner case you won't get ever to a state where you have a working library at all.
  7. Didn't I say to configure the parameter as: Adapt to Type, Array Data Pointer???? Also it would be more correct to write your function prototoype like this: int32_t LV_DLL_EXPORT func(table *pointer); That is not causing your crashes (the previous point about configuring the parameter however sure is), but it simply makes things more clear that way. Also what top secret nuclear project are you working at, that you still refuse to attach even your actual test VIs, which surely won't reveal your super duper algorithme that you will only eventually implement in the code after your principal interfacing to your test VI is working?
  8. 2) You configure the Call Library Node parameter as Adapt to type: Pass C Array Pointer. 4) Just because you assign the pointer value of memory location to a pointer parameter does nothing about making sure the contents of the memory area is copied into that parameter. table datatable[16]; (here is C allocating the memory for the array with struct of integers if i am right) int32_t func (struct *pointer) { pointer = datatable; } This only assigns the memory address of datatable to the pointer. However the calling function never sees that pointer nor any data in the pointer. You simply destroy the data area that LabVIEW has allocated and on return of the function LabVIEW can't help but trip over the trap you laid out for it. You would have to do something like int32_t func (struct **pointer) { *pointer = datatable; } but that only works for C as caller (and not like this since the datatypes are not the same). LabVIEW can't deal directly with pointers. More appropriate would be: int32_t func (struct *pointer) { *pointer = *datatable; } But that works in standard C not for all compilers and even in modern C++ it would cause a compilation error since the datatypes are incompatible. The best thing to do would be: int32_t func (struct *pointer) { memcpy(pointer, datatable, sizeof(datatable); } And making sure that you allocated a big enough variable in LabVIEW to be passed to the pointer parameter. If the dataarea from LabVIEW is even one single byte smaller than the length of datatable, very bad things will happen for sure.
  9. The biggest problem is about trying to tackle this without having a fundamental understanding of C and memory handling in general. 1) yes 2) 16 times 7 times 2 bytes, plus some LabVIEW dataspace for management of the array but you do not want to pass the LabVIEW array to the C function but the C pointer to the array. Only specially written C code can directly handle native LabVIEW arrays and strings. 3) Code Interface node is an old legacy technology to incorporate external code in LabVIEW. It is only present in some of the LabVIEW platforms nowadays and completely missing on any 64 bit versions of LabVIEW and also all realtime targets. LabVIEW ceased to ship with any tools that were necessary to create CINs many versions ago. 4) You can return data from a function through its parameters and are not limited to the function return value. Also it is good courtesy to mention that you have crossposted this in the NI forums already. The LabVIEW community is not that big that nobody would notice, but it helps others to see if they should spend any time to provide an answer that was already given elsewhere to the same person.
  10. From what I could see on the website they are mostly into high end hardware for space/defense/airplane industries and there USB doesn't really fit into very well in terms of reliability and harsh environment resistance. Haven't seen any prices but it would not surprise me if their price is in the same range or higher than NI.
  11. Except that when you follow the link from Dave's post you get to a page which looks like the card he is talking about and in red letter New Product! afterwards. After about 8 years it would seem a little strange to still claim it's a new product. CPCI isn't as quick paced as general computer technology but that slow!!!!???
  12. AVI is really only a container format and mostly meant by Microsoft to be used for real world video. What format the data is actually written in depends highly on the available codecs on your machine. Most likely it won't support U8 and/or greyscale without installing a very specific codec that supports such a format. And if you created such a formatted AVI you won't be able to replay it on machines that have not the same codec installed. The Windows AVI interface correctly changes the format to an available codec format that, at what it believes at its own discretion is the closest match to the incoming format. If you check the format of the resulting AVI file with some AVI file format checker you will see that it is already RGB when written on disc and the reading will simply read in what is on disc and has no way to magically know that it should convert it back to U8 greyscale.
  13. The Blogs seem to have gone and I wonder if there is still any way to access their content other than trying to find them in the wayback machine.
  14. BSD is a very permissive license and as such should not pose any problems. In fact the Open Source license usually only really matters for reuse libraries. This being a tool it is of less concern, even GPL (with a small exclusion clause that the SW may also be used within the closed source LabVIEW application) would work as all it disallows is to use the SW library for derivative works without releasing the entire source code of said derivative work. As a plugin for LabVIEW with aformentioned exclusion clause there is not really much you would take away from potential tinkerers with your tool/plugin. That said I usually use nowadays BSD for anything I want to make available as Open Source since it is the most simple license IMO. GPL and LGPL are about umtien pages of text now, that even lawyers disagree about what it all means
  15. Most likely this is Excel itself that is doing this. While loading the data file, imagine what would happen if another application is at the same time writing to it. This could result in inconsistent data being read during the loading process so Excel simply disallows write access for other applications during loading (and probably fails the load if another application has already opened the file for write access). After the file is loaded and all data is safely in memory, Excel probably simply closes the file altogether or at least resets the DENY rights on the file. The read only settings when opening a file is not so much how Excel opens the file itself, but an internal setting of a workbook that disables editing of that workbook.
  16. It shouldn't. But then without seeing what your working Java application does, or how your Android app does setup the communication, it is mostly poking in the mist as what might be required to make this work with LabVIEW.
  17. Well, theoretically you could use TCP/IP, UDP or even some other low level protocol, so yes you should be more specific! "I want to go to New York" is usually not enough for someone to help you come there. It's quite helpful for that person to know if that should be by train, airplane, ship or maybe rocket and if you start in Paris/France or in Washington DC. If it is TCP/IP or UDP you can do it in LabVIEW but the principle does differ somewhat since one is a connection based protocol while the other is not. Assuming you use TCP/IP you would simply look in the Example finder for the "TCP Communictor - Passive" example, open it, configure the port to what you have and start it then run your Android app. Obviously you would have to tell your app which IP address your PC has. If it is UDP you rather want to look at "UDP Receiver" in the examples. And if it is something else than TCP or UDP you won't be able to do it in LabVIEW native but will have to interface to the OS socket library through Call Library Nodes to do it.
  18. Are you using TCP, UDP or some other transport protocol? If you use TCP or UDP you will look into the respective function palette in the Data Communication->Protocols palette.
  19. There is another problem about the question with clusters. It is not very specific as to what is wanted. Should it be a cluster where each element in the cluster is matched with a column in the database table? If so should it be matched based on cluster element name matching the column name or rather its ordinal value in the cluster match the row number? What about if the cluster doesn't match the rows in either case? Or is it about storing a cluster as binary blob in a single column? Questions, questions!!!!
  20. Well yes but the CWD is a broken concept for multithreaded applications anhow. So why trying to risk anything aside from that changing this path might break some other broken implementation elsewhere in your application, like in a third party DLL. The best solution is to make sure that the DLLs are put in a place where Windows will find them, that would be most likely a directory in the PATH environment variable in the development system and the application directory in a built application. If you absolutely need to trick Windows, I would do it a bit different. Just call LoadLibraryA() with the library path where you now call SetCurrentDirectory(), That loads the library into the process and then Windows will hit that library name in my earlier list in step 1) already. Achieves the same, requires also just one Call Library Node but avoids potential race conditions and breaking other compoments that might rely somehow on CWD being set in a certain way. Just make sure to not call LoadLibrary() many times, and strictly speaking you should also FreeLibrary() but unless you work in a plugin situation where you might unload the plugin sooner than later, it really doesn't make a big difference if the DLL remains loaded in the process until the application is quit.
  21. I would consider modifying the current path (CWD) to achieve this not only hacky but really a potential race condition in a multi-threading system like LabVIEW. There are various Windows APIs which will themselves modify the CWD internally with the File Dialog API being one of the more prominent ones and there is definitely a chance that something else in the application might call some functionality that changes that path between the time you call SetCurrentDirectory() and LabVIEW gets around to load the library. That's admittingly a small time window, if you program your VI right, but the sheer possibility of this makes me run away from this solution.
  22. It's not LabVIEW which is searching the dependent DLL but Windows. LabVIEW only knows about the DLL that you reference in the Call Library Node and nothing else. It asks Windows to load the DLL and the Windows loader then finds in the DLL references to other DLLs and tries to load them. For that Windows uses a predefined search strategy and looks in following locations: 1) if the same DLL is already loaded in memory it uses that 2) in the application directory (that is the directory where LabVIEW exe resides for the development system and yourApp.exe for a compiled application) 3) in the Windows directory 4) in the system directory 5) in the current directory (typically the directory where your application was started from but also the last directory in which the File Dialog box was positively dismissed inside your application) 6) in any directory that is named in the PATH environment variable Put that DLL in one of these directories (and make sure to include it in any build of your application too) and things will work.
  23. Just a small note: I was only marginally involved in this library. The main developers were Jim and to some degree Heiko. I had at some point made my own version and likely posted them on some forum but if anything it only served as some inspiration for this library. Looking through my archives I found this library which is already quite old and not very well tested if I remember correctly. But it did implement the HTTP1.1 protocol including the HOST field. The top level VI is meant to be HTTP Site Downloader but I never got around to implement the actual parsing of the HTML document and adding its contained links to the download queue. But it serves as a good idea how the HTTP Parse URL and HTTP Download Link are meant to be used. And yes it does not implement authentication either. I find basic authentication useless and the digest was a little bit complicated although I meant to get around to implement that eventually. It's LabVIEW 6.1 but should still be loadable by LabVIEW 2013. HTTP.zip
  24. Your DLL depends on an SxS assemby that is not installed on your machine. Most likely it was compiled with Visual C++. You need to find out what version of Vsual C++ was used to compile your DLL and then download the Redistributable C Runtime Library for that version from Microsoft. More generally the manufacturer of your DLL should have provided you with an Installer for the DLL that takes care about installing the DLL on your computer and also install all the necessary dependencies it has.
×
×
  • Create New...

Important Information

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