LabVIEW

cancel
Showing results for 
Search instead for 
Did you mean: 

Passing arrays with Call Library Function does not work after application builder

Solved!
Go to solution

Calling a DLL with Call Library Function which requires an array of data works correctly in Labview, but after building an exe with application builder, the call no longer works.  Dereferecing the pointer in the DLL retuns all 0s and not the actual values.

0 Kudos
Message 1 of 10
(3,683 Views)

Hi Gboggs,

 

You need to make sure that you build everything within "Build Specifications" in your project so that the application builder can reference these files properly. I got it working from my end. Go ahead to give that a try!

0 Kudos
Message 2 of 10
(3,641 Views)

When you run the executable there should be 3 popups.  Can you please let me know if they show Hi Joe and Billy?  If they do, can you please let me know what you changed in the builds specs?  Thanks.

0 Kudos
Message 3 of 10
(3,620 Views)

When I tried to unzip your Project, there was no SharedLib.dll (open the Project, look in Dependencies, see if anything is missing).  If it were there, then in the Build Specification for CallDll, you would include SharedLib in the "Always Included" section of Source Files.

 

Bob Schor

0 Kudos
Message 4 of 10
(3,603 Views)

I didn't include it as you should be able to first build the dll and then copy it to the data folder of hte calldll executable.  

0 Kudos
Message 5 of 10
(3,537 Views)

I added in the prebuilt exe and everything else to make it easier to understand the issue.  If you run CallDLL in labview directly, there will be 3 popups generated which is the data that is passed to the DLL.  If you run the executable version of it, the Popup is still created, which shows that the DLL is being called correcly, but there is no longer any text data.  This is because the memory space that the pointer points to, is either no longer the same (memory protection) or has been deleted (don't know why this would happen).  If anyone has any ideas, please let me know.

0 Kudos
Message 6 of 10
(3,488 Views)

I did not run your code because it is a little unclear to me what it does.

 

Two things:

 

First, is the DLL you are calling the DLL-ified version of PopUpNames.vi? Then the problem is likely that the panel is not being built into the DLL.

 

When LabView builds an application / dll, it strips the front panel and block diagram from all VIs that it doesn't think need to show a panel at run time. This reduces file size and increases code security. The App Builder's panel inclusion logic can be overridden by Build Specifications -> Source File Settings -> Remove front panel. A better method is to put a property node on a control in a window you want to show marking it "visible"; this is sufficient to tell the App Builder it should keep the panel.

 

Currently Source File Settings shows "no dependencies" (clearly incorrect---another evil side effect of Express VIs I guess) but if you change the settings as shown below to keep ALL panels, one might hope the App Builder can figure it to keep the panel when it deconstructs the Express VI. (Alternatively convert the Express VI into a regular one.)

 

sfsettings.png

 

A second comment: I am a bit flummoxed at the larger goal here. You are calling LabView DLL from LabView, which doesn't make a lot of sense, so I assume your larger goal is to call LabView from C or vice-versa. In that case be aware that your DLL is x86 (32-bit) but you are passing 64-bit ints as your pointers. In this case it is 32-bit LabView with 32-bit pointers in embedeed in 64-bit containers calling 32-bit LabView with 32-bit pointers in embedeed in 64-bit containers, so it all works, but if your going to call this from C or whatnot you're going to have to follow that same design.

 

When calling C code the LabView Call Library Function does have a "unsigned pointer-sized integer" data type that always appears to be 64 bits in the dev env but which actually passes a 64 or 32-bit int to the DLL depending on the environment. The "pointer sized int" has to be 64 bits in the "LabView" part of the code because LabView's strong typing requires the data type to be determined at compile time. Casting all pointers to the largest data type in LabView makes it possible to write platform-independent code, but down at the Call Library level you still have to put the right number of bytes on the stack.

0 Kudos
Message 7 of 10
(3,478 Views)

Hi Rob,

 

Yes this is just to solve/understand the issue for a much larger project.  We mant to make a plugin system to analyse data which would allow us to push trow DLLs into a subfolder so that the next time the program runs a periodic analysis, it will load all the DLLs found in the folder and each DLL run its own analysis on the data.  The main program loads the data into memory and passes that data to the DLL so that you don't have to re-read the data for each DLL.  Currently this is the issue which is preventing us from completing this system.

 

I'm also aware of the pointer size issue, and for the actual system, we are passing pointer sized values.  

 

I made the changes to the source settings that you pointer out, and the issue still occurs.  I also replaced the express vi with a standard vi and no change in the behaviour.  Works in Labview but not built exe.

0 Kudos
Message 8 of 10
(3,464 Views)
Solution
Accepted by gboggs

So finally figured it out.  It seems that you can't use the pointer utilites in a built exe  such asGetValueByPointer.xnode.  Once I replaced the calls with DSNewPtr  and MoveBlock library calls, everything works as expected.

0 Kudos
Message 9 of 10
(3,398 Views)

I just saw a discussion of this, with a solution, on LAVA: https://lavag.org/topic/18571-calling-getvaluebypointerxnode-in-executable/

0 Kudos
Message 10 of 10
(3,362 Views)