Jump to content

Mark Smith

Members
  • Posts

    330
  • Joined

  • Last visited

  • Days Won

    5

Posts posted by Mark Smith

  1. OK, now this is getting complicated - probably beyond my ability to help! I assume that when you looked at the dependencies of the DLL in question, it pointed to the folder in your \WINDOWS\SxS directory (that's the Windows Side-by-side directory). I'm not very familiar with that but a little quick reading indicates that it's a place that COM DLLs can live "side-by-side". Evidently, XP and Vista can use "Registration-Free COM" activation and when this happens COM DLLs get installed in the SxS directory, along with a manifest and a "security catalog". This means that the COM object doesn't get entered into the system registry - rather, at run time the calling application (the EXE) now must reference a manifest file (typically in the calling EXE's directory, as far as I can tell) that contains information about how to load files from the SxS directory. Since you had a system that worked when VS 2008 was installed, the manifest information must have been somewhere in the 2008 hierarchy or if you built the dlls yourself they were likely created when the dll was compiled and linked - if possible, go back to your VS2008 development machine and see if you have any *.manifest files created when you created the dlls. Without the manifest files, your dll can't link to the ms runtime library dlls because they aren't registered in the system registry and there's no information about which SxS files should get loaded. Please note that all of this is pure speculation ;)

    Here are some links that provide more (a lot more) information

    http://msdn.microsoft.com/en-us/library/ms973913.aspx

    http://msdn.microsoft.com/en-us/magazine/cc188708.aspx

    Maybe someone here really understands this stuff and can help.

    Mark

  2. That's one of those really useful Windows error messages! My guess is that your dll is linked to the debug versions of some DLL - likely something like the msvcrtd.dll (the Microsoft C++ Runtime Library (debug version)) which gets loaded with VS but not with a standard Windows install - Windows will install the msvcrt.dll (doesn't include any debug info) but not the debug version. So, if your dll was built with the dynamic calls (http://msdn.microsoft.com/en-us/library/2kzt1wy3.aspx) into the debug library and the VS uninstall removed them, it won't run and you get the helpful error message. If possible, build your DLL with the /MD compiler option instead of the /MDd and this problem may be solved. If you can't recompile the dll (maybe it's not one you wrote) then use Dependency Walker

    http://www.dependencywalker.com/

    to find which dll is missing that your dll is trying to call and find a copy of that dll and copy it to wherever your dll is looking for it.

    Mark

  3. John,

    This might be something that's useful (the third item on the page)

    http://forums.ni.com/ni/board/message?boar...=277358#M270293

    I found this the other day when I was wondering about how to profile reentrant VI's. I haven't used it yet but it looks like you could have each reentrant instance attach their names to a message on entrance and exit and find out how much time is consumed (with the added complication of guessing how much overhead this call adds).

    Mark

  4. QUOTE (bandersen @ Oct 31 2008, 03:21 AM)

    Use NI's Measurement Studio if you want to use the plotting features like the ones available in LabWindows or LabVIEW in Visual Studio. These toolkits are designed for Visual Studio and the .NET environment and there's lots of information, help files, etc. to do just what it appears you want to do. See this link for a quick description.

    http://cnx.org/content/m14741/latest/

    I don't have any experience trying to call LabWindows libraries from Visual Studio, but the error you show in your original post is definitely a linker issue - your code is not linking properly to the libraries. I don't have any ideas about how to fix it.

    Lastly, if you have LabWindows/CVI, it includes an integrated development environment (IDE) and that's the best way to program in C and use the LabWindows libraries.

    Mark

  5. QUOTE (kennoncotton @ May 15 2006, 09:32 AM)

    Tim,

    Sorry I took me a while to respond to this after I said I would in that other thread.

    Ok, so the other thread mentions that in general if you have an EXE that has plugins, the EXE needs to have everything it needs to run and each plugin should have everything it needs to run, in case the EXE changes or some of the plugins aren't in memory. So that should be it for the 1003 error, right? Well there is new way in LabVIEW 8.0 that you can end up with a 1003 error on your plugin VIs if they use VIs from Project Libraries and your EXE uses VIs from the same project Library. You mentioned Mean.vi which is probably one of the VIs that is broken in your plugin and it is part of a Project Library. Also you probably don't have any of your user.lib VIs in Project Libraries, so that is why you are seeing a difference.

    The other way to get this 1003 error is by trying to have 2 Project Libraries of the same name in memory at the same time. This doesn't happen in the development environment because there is only one copy of each Project Library. However in an EXE with plugins, where the plugins were built separately from the EXE (Method B from the other post) you can end up with a copy of the .lvlib in the exe and another copy in one or more of the plugins. This seems harmless since the first one in memory is the one that is used (just like VIs), but during the build process we remove unused members of the Project Library in the EXE. And since a VI knows which Project Library it is a member of and a Project Library knows its members. So if the Project Library is already in memory and a VI is loaded that says it is part of the Project Libary, but the Project Library doesn't think the VI is part of it, then the VI will be broken. I think this why you are seeing the 1003 but it works when you load the vi.lib VIs from vi.lib since in there is only one copy of the Project Libraries being used and no references have been removed from them.

    Lets take a specific example where you are using some of the Analysis VIs and the EXE only uses Histogram.vi and the plugin only uses FIR.vi (I got a CAR on this last week and wrote a long explanation that I'll copy and paste):

    When the exe is built it includes NI_AALBase.lvlib and Histogram.vi in the exe, since Histogram is the only item in NI_AALBase.lvlib used by the exe, App Builder by default removes all the other references that NI_AALBase.lvib has. The new copy of NI_AALBase.lvlib inside the exe is essentially a Project Library with one item referenced in it (there may be some subVIs if Histogram has any that are part of the .lvlib). When the Source Distribution is built the new copy of NI_AALBase.lvlib inside the source distribution has all its references by default because Source Distributions keep them. Even if you trimmed it down in the Build Specification it would only have a reference to FIR.vi which wouldn't be helpful either.

    As I said, a VI knows what .lvlib it is a member of and a .lvlib knows what VIs are part of it.

    So when the EXE is launched it loads the EXE's copy of NI_AALBase.lvlib into memory. Then the EXE is calling the Source Distribution as a plugin so the VI being called tries to load FIR.vi which knows it is part of NI_AALBase.lvlib, well that is already in memory, so the Run-Time Engine can't load the source dist copy of NI_AALBase.lvlib because a library of the same name is already in memory (so it doesn't matter what links that copy contains). But the copy of NI_AALBase.lvlib in memory reports it doesn't have FIR.vi as a member of it (remember the EXE copy only has a link to Histogram.vi). So FIR.vi is broken because its owning .lvlib isn't found.

    The removal of non-essential items is basically a size optimization, so what can be done? Well, not be optimized, by including the entire Project Library into the EXE and the source distribution. That way the 2 new copies of NI_AALBase.lvlib will have links to all the items in it, so the first one loaded will respect everything else.

    Either 1) move the NI_AALBase.lvlib out of dependencies into the tree with the rest of your source and include it as a Dynamic VI in the EXE build and Always Include it and its sub items in the Source Distribution. There will still be 2 copies of NI_AALBase.lvlib but they both contain links to all of the items in the Project Library, therefore which ever one loads first, it won't prevent other VIs from running. Also all the items directly referenced by NI_AALBase.lvlib and their dependencies will be included.

    Or

    2) Uncheck "Disconnect Type Definitions and Remove unused Polymorphic VI instances", that also removes unused .lvlib components if it is checked (maybe we should make those separate options). This will cause all the contents of NI_AALBase.lvlib to be included and the contents of all the .lvlibs it links to. Since NI_AALBase.lvlib contains VIs that have references into NI_AALPro.lvlib, all of it and its dependencies will be included, even if they aren't used by the code. So this can get very big and I wouldn't recommend it (for .lvlibs without circular links, this would be okay).

    With method 1 you could also build the .lvlibs and the files referenced by them and their dependencies into the same location on disk. That there would only be one copy and each build would overwrite it.

    I have some thoughts on how to make this better for future versions of App Builder/LabVIEW, but right now it only takes what you tell it you need or it takes it all.

    Kennon

    I'm running up against this same problem in an app I'm working on (in 8.2.1) and I have a couple of questions: First, is this still the behavior in LV8.6 when incuding project libraries? Or does 8.6 make handling this situation easier somehow? - I could migrate the project to 8.6 if that will help. Second, if I distribute the original EXE as a LLB (source distibution) it will have copies of the lvlb files that contain all member references, right? And then if I call this LLB from a shell EXE (that does nothing but call the LLB that used to be the EXE) and then the LLB that used to be the EXE calls into another LLB that includes a copy of the same lvlib, there shouldn't be a problem? Right?

    Thanks for any help!

    Mark

  6. QUOTE (andymatter @ Sep 19 2008, 06:09 PM)

    Hi,

    I'm using a third-party USB driver in the form of a .NET assembly DLL to talk to an instrument we are building. The driver's documentation provides a C# example for implementing data transfers that make the best use of available bandwidth on the USB. I am attempting to duplicate the example's functionality in LabVIEW, but this involves an oddball pointer type conversion that does not seem to translate very well into the LabVIEW paradigm (i.e. I've tried everything I can think of, but I can't figure it out).

    The specifics are as follows:

    The driver provides Begin/WaitFor/Finish-transfer methods that all require an array of event-references(?) to be passed between them. This array is a 1D array of 20 bytes. In the C# example I'm working from, the event-reference is written-to/read-from the array through a struct object provided by the driver. The struct serves as a "map" to expose the byte array as a set of U32 values that I can get/set through a .NET Property Node.

    1) How do I reference the array through the struct object in LabVIEW? See the contents of the ZIP file.

    Alternatively, I could avoid using the struct object altogether in LabVIEW by simply using the Type Cast function for the bytes[]/U32/reference conversion. The problem with this, however, is that I'm not entirely sure which 4 bytes represents which U32 value or what order the bytes are in. In order to find out for sure on my own, I need question #1 answered, so I can set a value and see how the array changes. Otherwise, if I can't use the struct object, can someone tell me...

    2) Given the info provided, where in the array can I assume the "hEvent" struct member to be (and its byte order)?

    If anyone could point me in the right direction, it would be much appreciated.

    Thanks.

    OK, a couple of things I think I can answer - in your VI example, you show an attempt to cast a .NET object created from an array to the struct - that won't work because the target struct is not an array - LV only knows how to create objects of the specified types listed in the help.

    Second, the actual layout of the data in the OVERLAPPED struct will always be exactly in the order described and will be packed as efficiently as possible (on byte boundaries) - that's what the

    [structLayout(LayoutKind.Sequential,Pack=1)]

    attribute means in the struct definition (http://support.microsoft.com/kb/922785). So you can always be sure the same data will be in the same place in the array. So in your alternative 3 in your LabVIEW code this will populate the correct location, although it is easier to create the buffer as U32's and then just address the array position. As far as byte order, it will be little-endian on little-endian machine (intel). But I'm not sure that really helps very much.

    Once you get past that, this starts to get tricky because this is "unsafe" C# code in the example - once you create an array of structs that contain hEvent handles as the last data element, now you have to use that in the code and make sure they stay in place. In the C# example, the array of OVERLAPPED structures uses the "fixed" keyword to make sure that the data array doesn't get arbitrarily garbage collected by .NET. You'll have to do the same thing with the data array you create in LabVIEW. So this starts to look like calling into a regular (unmanaged) DLL. This thread (http://forums.lavag.org/DLLs-that-expect-LabVIEW-data-to-stay-put-t8608.html) has some info about how to fix a block of memory in labview.

    So, what may work is to

    1) Create an array of uints - the array should be mutilples of five

    2) populate every fifth element with an event handle using the Pinvoke.CreateEvent (or you could bypass the double indirection of LV->.NET->WinAPI by calling CreateEvent from the kernel32.dll)

    3) Use the LV memory manager (from the LAVA thread above) to create a block of fixed memory and copy the array into it

    4) cast the pointer to this memory block into the .NET ref for the OVERLAPPED struct array

    5) Watch for memory leaks - you now have lots of potential to create them

    All this is pure speculation so take it FWIW ;)

    However, I read this in the CyUSB help

    "Again, the use of BeginDataXfer, WaitForXfer, and FinishDataXfer is the difficult way to transfer data to and from a USB device. This approach should only be used if it is imperative that you squeeze every last bit of throughput from the USB."

    Sounds to me like there's an easier to use synchronous method available. You can probably build your LabVIEW code on the synchronous calls and then add asynchronous capabilities easier using reentrant VIs and the VI server to launch multiple communication threads and don't fool with the internal asynchronous calls unless you absolutely have to.

    Mark

  7. QUOTE (Jeffrey Habets @ Sep 8 2008, 02:03 AM)

    I second what Jeffery said - it's not a question of being able to explain the error after it happens, it's a question of knowing exactly what errors might be generated so I can make intelligent choices of how to handle them at run time in my deployed applications. Seems there should be a better way than just trying as many potential run-time scenarios as one can think of and then writing the code to handle the errors generated - what about those scenarios you didn't anticipate? Now I've potentially got a customer calling and asking why his system just generated some error that shut down his test when if I had explicit knowledge that error could be generated I might have been able to handle it much more elegantly.

    Mark

  8. OK, I'm a little late to this thread, but I was just coding in LabVIEW and trying to do some intelligent error handling and 1) either I identified a glaring deficiency in LabVIEW or 2) I'm just ignorant and don't know where to look, but is there any document or help file or something that specifies what error codes LabVIEW functions return? And I don't mean an error code list that has headings like "General" - 1094 - 1157 where I get to guess which one gets generated or just try to handle the 64 possible errors. I mean something like the MSDN on-line support where I can find which exceptions a method is expected to throw in the documentation for that specific method. I open the LabVIEW help for a given function and sometimes there's some info (like for Obtain Queue) but most often there's not. This makes it really hard to anticipate and handle run-time errors - what do you guys do?

  9. If you're comfortable with .NET and don't mind a Windows-only solution, I've had good luck with the .NET products from Advanced Intellect

    ( http://www.advancedintellect.com/ ) I haven't used them with LabVIEW (I used them with C#/Visual Studio 2005) but they worked well for secure email and I got good support from the vendor. It should be relatively easy to create a dll (assembly) with methods optimized for calls from LabVIEW.

    Mark

  10. Don't know if this will help or not, but I had a similar problem in that I kept getting the message a file was missing and I could not find any missing file. I started eliminating VI's until I could get the exe to build. Turns out that there was a single control reference that had the "Include Data Type" option selected. The control reference had been created from an old type def (no longer in the project). If the missing type def had been included in the VI, the VI would have broken and the problem would have been obvious. Just having the "Include Data Type" selected, even though the data type was missing, did not break the VI until building, when apparently the app builder looked for it and could not find it. Unselecting that option allowed the project to build.

    Mark

  11. QUOTE(CTITech @ Feb 21 2008, 12:08 PM)

    The application is medical and mil, so I need presion. So im open for options. :headbang:

    If you need traceability and precision for a mil spec/medical measurement, then you really ought to consider using a calibrated DMM. The time you'll save in configuring the measurement and the added confidence you'll have (and paperwork trail to justify that confidence) will be worth the money.

    Mark

  12. I'm no expert here, but it seems like you could put a precision resistor in parallel w/ the resistor under test and use

    Req = Rt * Rp/ Rt + Rp where Req is the resistance measured, Rt is the DUT, and Rp is the precision resistor. Then solve for Rt. Size the precision resistor so that the Req is always under 10K even when testing the 300K resistors - this should be a little more than 10K for the precision resistor.

    Mark

  13. I have a copy acquired in the last six months or so that replaced one that I loaned to a colleague. He had an unfortunate incident with a diet soda, I believe, and he graciously replaced my original. The diagrams in this printing, while I would not call them "Art Book" quality (well, I really wouldn't call them even "Comic Book" quality) are readable and the book is useable.

    Mark

  14. QUOTE(tcplomp @ Feb 13 2008, 07:19 AM)

    Ton,

    Thanks for the reply - Here's why I think LabVIEW doesn't support the IPv6 protocol

    http://digital.ni.com/public.nsf/allkb/46A...6256D4B005D3016

    which says (dated 07/19/2007)

    "Problem:

    Does LabVIEW and/or the Internet Toolkit for LabVIEW support the Internet Protocol version 6?

    Solution:

    No, LabVIEW only supports IPv4. National Instruments will continue to monitor the demand for IPv6 and may add support for this technology to future releases of our products."

    Yep, I would have expected that the protocol would depend on the what the OS supports (WinXP in this case), but to keep LabVIEW platform portable maybe the implementation defaults to the lowest common denominator (IPv4)?

    As far as what's so special about the hardware? Beats me, but the DUT's are a suite of devices that communicate with each other using IPv6 protocol and we have to be able to generate and receive command and control messages using IPv6 so we can emulate system hardware with the tester.

    Thanks,

    Mark

  15. I have just joined a project where we need to communicate with custom hardware using the IPv6 protocol. A quick search indicated that LabVIEW does not support the IPv6 protocol (someone PLEASE tell me I'm wrong!!!). The intention was to use LabVIEW for this project since we have a team of experienced LabVIEW developers and we need to control other instruments over serial and GPIB - not to mention that we have a very short time to delivery and LabVIEW is about the only tool that gives us any chance of success! I'm an experienced .NET developer, so my first thought is to create a .NET DLL that wraps the IPv6 networking tools available in the .NET 2.0 (or 3.0, although I haven't used it) framework and call that from LabVIEW. I'll build a LabVIEW wrapper around the DLL that encapsulates all the functionality so that the DLL could actually be anything that supports IPv6 - the reason for this is that somewhere down the road the customer may ask for inter-platform portablility (to Linux) and then the DLL could be replaced with a .so (is that right? My Linux knowledge is pretty rusty) and the code would still work. At any rate, we'll still have LabVIEW for all the UI, instrument control, configuration control, etc. Please offer criticism of this approach and feel free to suggest any alternatives.

    Thanks for your help!

    Mark

  16. I have a project where the structure is a top level .exe calling into libraries (llb's) of VI's using strictly-typed VI server calls. The top level .exe calls into LibraryA.llb and LibraryB.llb. LibraryA.llb also calls into LibraryB.llb. That means the VI's in LibraryB.llb that wrap the VI server calls get built into the Top Level.exe and also built into LibraryA.llb. When the Top Level.exe runs, the call into LibraryA.llb fails with Error 1003 and the message

    LabVIEW: The VI is not executable. Most likely the VI is broken or one of its subVIs cannot be located. Open the VI in LabVIEW using File>>Open and verify that it is runnable

    VI Path: C:\Path to LibraryA\Interface.vi

    I also dynamically opened the panel with a VI server call (without trying to run) and sure enough got a broken error and the message "VI has an error of type 2002200. The full development version of LabVIEW is required to fix the errors" This is pretty cryptic - can someone perhaps explain the nature of this error?

    So I open this VI from LabVIEW and it's just fine. If I remove all VI Server calls to LibraryB.llb from the Top Level.exe, all runs as expected. The VI at the path above opens and runs just fine. As far as I can tell, the problem is that there's a name collision because the VI server wrapper VI's used to call into LibraryB.llb are already loaded into the Top Level.exe when LibraryA.llb tries to load them from the LibraryA.llb.

    Is my diagnosis correct? What's the best workaround?

    Thanks,

    Mark

    NOTE: I have cross-posted this to InfoLabVIEW as well

  17. I agree with Tomi that in principle, OO code is the way to go. However, there's at least one shortcoming of the current implementation of LVOOP that you should be aware of. I recently wrote a LVClass (using LVOOP) that I wanted to distribute as "class Library" - that is, a set of VI's installed to a specific directory. As I found out, the Source Distribution build option in the Project Explorer does not work properly and that cascades down into being unable to use the project explorer's installer dialogs to build an installer. This could be a severe shortcoming for an instrument driver library that you would want to distribute with an installer. Here's my question to NI Support and their answer

    Question:

    I have a project with a LV Class. I want to 1) distribute the LV Class as part of a source distribution and 2) create an installer for the source distribution. While I can build a source distribution that includes a LV Class, I cannot generate a preview for the source distribution. This apparently prevents me from creating an installer for the source distribution, since all I can see from the Source Files dialog on the Installer Properties is <Error generating preview>. A simple example is attached. Is there a workaround?

    Answer:

    "...

    This limitation of the LabVIEW class is a known issue with LabVIEW 8.20, and is being addressed in a future release of our software package. There currently is not a workaround for this issue. However, I am interested in working with you to try and find a workaround. Can you please give me information about your desired behavior. Are you simply looking to move the class to another computer?

    ..."

    You could most likely get around this limitation using a third party installer if you want to go this route.

    Also, building a class with an "interface" like implementation (methods meant to be overridden in child classes) requires Dynamic Dispatch terminals. Methods built with Dynamic Dispatch terminals cannot be invoked using VI Server calls. This may or may not be important to your implementation, but it was an important limitation to me. All in all, I decided LVOOP in LV 8.2 is a good start but not ready for prime time. I'm interested to see what gets addressed in LV 9.x.

    Lastly, I don't have much experience with the third party LabVIEW OO tools, so there may be some options there that would work well for you.

    So, given the current state of LV, I would agree with LV Punk that using the LVlib (LabVIEW Libraries) to build a set of driver libraries would work well. The source distributions and the installer are easy and in my experience reliable using LVLibs.

  18. I'm wondering if anyone out there has done an implementation of the XML-RPC protocol in pure G? I'm working on an application where a top-level control program is written in Java (by another developer) and deployed on a Linux X86 machine. I plan on using LabVIEW compiled to the Linux platform for communication and control with the instrumentation required and then communicate with the Java program thru the XML-RPC protocol (the LabVIEW app will become an XML-RPC server). Any thoughts appreciated - even if the advice is "you gotta be out of your mind". Better to know now if there are better options!

    Mark E. Smith

    Sandia National Laboratories

    505-284-5293

    mesmith@sandia.gov

  19. Hmm, your VI does pass a non-zero refnum, but also no effect on the position of the file dialog window.

    I'm attaching my VI, replacing the App.ParWinforDlgs property node with Mikkel's VI doesn't change anything. Maybe the mistake is at some other place?

    Thanks

    Guenther

    Download File:post-3733-1170936325.vi

    I remember this same dilemma - my fix was to write a simple .NET DLL that encapsulates the call into user32.dll to get the window handle and then implement the IWin32Window interface to wrap the handle and then hand the ShowDialog the wrapped handle internal to the DLL instead of as part of the ShowDialog call from LabVIEW - might seem kind of clunky and it requires a DLL, but it works. It seems you could do the work of wrapping the handle in LV w/.NET calls after you use Mikkel's vi if there's a way to implement a .NET interface from LV - anybody know? Then you could avoid carrying around the extra DLL. But, more than once, I've found the best way to use the .NET namespace from LV is to write wrappers that expose exactly the functionality you need since the .NET syntax is optimized for C# or C++/CLI and not for LV. Example attached (LV7.1)

    Download File:post-1322-1170966265.zip

  20. index.php?automodule=downloads&req=display&code=sst&id=64

    File Name: ActiveDirectoryTools

    File Submitter: mesmith

    File Submitted: 8 Dec 2006

    File Updated: 12 Dec 2006

    File Category: Remote Control, Monitoring and the Internet

    This VI uses a .NET 2.0 DLL (DirectoryTools) to search Microsoft Active Directory. The DirectoryTools DLL uses the System.DirectoryServices namespace. The DLL exposes some simple functionality to LabVIEW in a form more user friendly to LabVIEW than direct calls to the System.Directory classes.

    Important Note: This implementation will only retrieve the first property of any record that matches the PropertiesToLoad - additional instances of an identically named property in a record are not returned

    Using this VI - this VI was designed to return all the computers on a given MS Windows network. The default filter (objectClass=computer) along with the default PropertiesToLoad of "cn" (common name) will return the name of all computers registered on the network. Any valid filter string and property may be used.

    Mark Smith (mesmith@sandia.gov)

    Click here to download this file

×
×
  • Create New...

Important Information

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