I'm sure this is something stupid, but after 2 hours of trying to figure it out I give up.
I'm making calls to user32.dll. Built several times, never had a problem. Randomly the compiler started including it as part of the build causing the application to crash instantly. I can't find any settings in the a compiler that would either allow or prevent this.
What am I missing?
Solved! Go to Solution.
The solution you found does solve your problem but might be troublesome if your application/library contains other Call Library Nodes that may need to have their DLL distributed with the VIs/built application.
What most likely happend is that one of the Call Library Nodes got modified to contain the full path to user32.lib. LabVIEW considers Call Library Nodes that use the full path name to call into private DLLs that need to be part of the application itself, and therefore the application builder will normally copy the DLL into the built application. If the library path only contains the DLL name itself without any path then LabVIEW considers this a system DLL that will be provided by the system itself and therefore doesn't copy the DLL into the built appplication. You can see an explanation of this behavior in the LabVIEW help: http://zone.ni.com/reference/en-XX/help/371361M-01/lvexcodeconcepts/locations_for_shared_libraries/
Now if you go into the Call Library Node and change the library name to "user32.dll" only instead of "C:\Windows\SysWOW64\user32.dll" you can leave that checkbox in the build settings unchecked and LabVIEW will still not copy user32.dll into the application build. Unfortunately if you go back into the Call Library Node and look at the path you will see the full path but LabVIEW will remember internally only the DLL name until you go with the cursor into the path control and then quit the Call Library Node dialog and choose to save the VI. LabVIEW considers the path to be modified to the new full path and stores it as such with the VI and now it considers the DLL as a private one, eventhough it is located in the Windows directory.
It's an usability issue that I have brought up several times already. The problem is that there is no good automatic solution, since blindly excluding certain paths from treating the DLL as private won't work either since those paths can also change, depending on the Windows version, language setting and even profile settings made by the administrator.
Personally I would prefer if there was an extra checkbox alongside the library path where one explicitedly can select if a DLL should be considered application private or system global and using that as hint for the application builder, but the drawback of this is that there is then one more control in the Call Library Node dialog, which already is so complex that it is beyond comprehension of most LabVIEW users.
Interesting... I didn't know that. I figured that LabVIEW had some method for determining if it needed to include the dll or not, but didn't know it decided.
I agree with you on the checkbox, and that the Call Library Node is overly complex. One of the biggest pet peeves I have with LabVIEW is how complex making Windows system calls is. This includes the Call Library node as well as making .NET API calls. It drives me nuts trying to navigate through the assembly list with a scroll bar. Then through the objects. Then through the constructors... and then repeating the process for every .NET object I need as an input to other calls. And on top of all of that frustration, sometimes you need a constant reference to a class (such as the System.Windows.Forms.SendKey class) instead of the .NET constructor node because it has no public constructors. Bah!
OK, /rant. Thanks for your response 🙂
Well, the problem about the Call Library Node is that interfacing to a DLL is a very low level thing. DLLs were not designed to be easy and simple to interface, just easy to use like a normal C library. But C programming is only slightly above assembly programming in ease of use and possibilities to do things on bare metal level. That comes with a huge gap between something like LabVIEW and using a DLL that was meant to be called from a C program. Simplifying the Call Library Node dialog would come at a tremendous cost of not being able to call many but the most simple DLL interfaces. Basically if you do not know how to call a DLL from a C program you have a serious lack of understanding about calling DLLs at all, and no super duper library wizard can take that away.
.Net is another story. The principle there is ease of use from high level languages and the .Net interface supports for that interactive discovery of an objects methods, properties and class interfaces. But most .Net objects fall into two specific classes:
1) a single interface with zillions of methods and properties. You don't have to browse through object hierarchies but the design of such an object is a complete nighmare and extensibility without breaking existing applications is pretty impossible.
2) an involved class hierarchy with many levels of inheritence and so on. Here the problem is that properly designing such a class hierarchy is a very sophisticated virtue that most programmers do not really fathom and even the few who do will often sacrifice a clean disign in favor of shortcuts and class interdependencies in the face of deadlines. Browsing through such a hierarchy can be pretty taunting and the fully interactive process of doing that in LabVIEW can be indeed pretty work intense. The same is true for any other visual style programming interface like Visual Basic or similar. And for C(++/#) you often get premade headers for using a specific library. Creating them however is an even more laborous and painstaking process than what you have to do in LabVIEW.
While there are certainly ways that the whole process could be a little more streamlined in LabVIEW, the fact that you interface to an external component remains and you have to provide the intelligence about what needs to be interfaced and in which way. LabVIEW only could guess and in general guessing just 99% right is still not enough and there is no magical AI that could get even close to such a high guess rate.
And on top of all of that frustration, sometimes you need a constant reference to a class (such as the System.Windows.Forms.SendKey class) instead of the .NET constructor node because it has no public constructors.
That's not LabVIEW's fault. Constants are generally implemented as static objects or enums and static objects can't have a constructor. You don't want to construct/ instantiate them every time you need them as that would take a bit of memory and in fact also runtime performance every time and that really can add up in a bigger applications. If the .Net interface was properly build by the developer you should be able to just select the actual method node and on the according parameter select "create constant" and you would end up with a real LabVIEW constant on the diagram but that is quite a work intense effort on behalve of the .Net component developer and therefore many .Net interfaces do not come with such a full featured interface description that LabVIEW could parse.
The .Net interface does not provide another way of definining constants that an interactive editor could easily create from.