NI TestStand

cancel
Showing results for 
Search instead for 
Did you mean: 

DLL Adapter: Change function name & params without unloading the DLL

Solved!
Go to solution

Hi,

 

I'm using teststand adapters API to dynamically build a DLL call step. Each dll function is called thru this "DLL Manager" sub-sequence. 

 

Tried 2 methods (here is an abstract of the code): 

1. ActiveX steps: 

CommonCModule.ModulePath = myDllpath

CommonCModule.FunctionName = myFunction  (note: this call unload the previously loaded DLL)

Module -> LoadPrototype

for( to set params)

 

2. Statement steps: 

RunState.Sequence.Main["Call DLL function"].TS.SData.Call.LibPath = myDllpath

RunState.Sequence.Main["Call DLL function"].TS.SData.Call.Func = myFunction (note: this one not, but the info seems to not be updated => The new function is not called properly)

Module -> LoadPrototype

for( to set params)

 

 

The two methods don't have exactly the same behavior, but work well for the 1st function that I call or work well if I unload the dll after step execute. 

 

However, is there a way to use these steps (or others) to setup the step, but without unloading the DLL between each call. In my test sequence, I have to OpenConnection with the UUT before launching my commands, so the dll must not be unloaded to keep the connection opened... 

 

e.g. 

1) OpenConnection()  => This function keeps the communication handle with the device

2) myCommand1()

3) myCommand2()

4) CloseConnection()

 

Thank you for help

C.

 

0 Kudos
Message 1 of 8
(5,480 Views)

Christiandb,

 

If I understood your code and your question correctly, you are trying to load a C dll and then use TestStand to programmatically change the function and parameters name. Then after making the changes you want to unload the dll for use?

Rob S
Applications Engineer
National Instruments
0 Kudos
Message 2 of 8
(5,414 Views)

Hi Hero,

 

You are correct. 

 

I use teststand api to programmatically load, change the function, and parameters name of a C DLL. A for loop modifies the function and parameters of the C DLL step and then execute it.

 

However, when I change the function name to launch (using the CommonCModule.FunctionName property), teststand automatically unloads the DLL before applying the change. Therefore, I can't open a connection handle with my UUT using one function and sends my commands with the others...

 

As previously mention, I try to perform something like show below, but using 1 C/C++ DLL step that the for loop reconfigures for each command:

1) OpenConnection()  => This function keeps the communication handle with the device

2) myCommand1()

3) myCommand2()

4) CloseConnection()

 

Finally, the DLL should be unload only at the end of the sequence overall execution.

 

 

p.s. maybe to clarify, I created an automated test engine (ATE) with a "DLL Manager" which loads a "custom test script" and decode all the functions with parameters of the dll to execute. In other words, each DLL function call is defined in an external file (test script) and teststand modifies the step at runtime per the file instructions. 

 

Thank you

C.

0 Kudos
Message 3 of 8
(5,397 Views)

Hi christiandb,

 

You should check out the linked documentation for more information about configuring DLLs to stay loaded after they've been called in TestStand:

 

Calling a DLL in TestStand by Reference: http://forums.ni.com/t5/NI-TestStand/Calling-a-DLL-in-TestStand-by-reference/td-p/1404112

Properties Tab: http://zone.ni.com/reference/en-XX/help/370052M-01/tsref/infotopics/pane_step_settings_run_opt/

 

Feel free to post back if you have any questions.

 

Myriam

0 Kudos
Message 4 of 8
(5,350 Views)

Hi all, 

 

To recap:

I'm looking for a method to dynamically loads and executes C/C++ DLL functions without unloading the DLL between each call. I already have a DLL manager that dynamically loads and executes dll functions, but it unloads the DLL between each call even if I set the unload option to: "Unload when sequence file is unloaded"...

 

 

The problem is: 

When I change the name of the function to execute (using the CommonCModule.FunctionName property), teststand automatically unloads the DLL before applying the change. Therefore, I can't open a connection handle with my UUT using one function and sends my commands with the others...

 

 

To help you with the understanding of my issue:

I created a simple example that will let you experiment the problem that I try to describ... You will notify that TestStand unloads the dll even if I don't request it... 

 

1) download the attached zip file

2) extract it anywhere

3) open sequence file "dll_called_dynamically.seq"

4) read comment of the first step of the sequence

>> To analyse the case:
>> 1) Break and run the sequence using step-by-step (use F10)
>> 2) Run one iteration of the loop to execute the dll once, ,
>> 3) Execute launch_listdlls.bat and verify in the outputfile.txt that the dll has been loaded (search for testlib.txt)
>> 4) Then, step over the step "Set Dll Function Name to call"
>> 5) Execute launch_listdlls.bat and you will notify that the dll has been unloaded... ...

 

The testlib.dll file provided in the zip file is a basic dll that I used to confirm my test engine. Mainly, it only performs additions on the variables passed as argument to the dll. 

 

The provided batch file executes the free application ListDlls.exe and create an outputfile.txt listing all currently loaded dll.

 

Please note that I use TestStand 2013

 

 

Thank you very much for your help,

C.

 

 

0 Kudos
Message 5 of 8
(5,163 Views)
Solution
Accepted by topic author NutaqTestDept

If I'm understanding your issue correctly, there are several ways to solve the problem. The easiest is by putting a call to the dll before your loop that you aren't modifying ever programmatically. That step will then keep the dll loaded (if any step which uses a dll is loaded, then that dll stays loaded. A dll is only unloaded when all steps which use it are unloaded.). Another option is to just internally have your dll call LoadLibrary on itself so that it never gets unloaded. You will then have to exit the process to unload the dll though. Another option is add code directly to the sequence which explicitly loads and unloads your dll using the Win32 APIs LoadLibrary and FreeLibrary.

 

That said, what you are describing, if I understand correctly, sounds like a very unusual usage of TestStand. It sounds like you are using TestStand as a dll caller rather than a sequencer, and are instead writing your own sequencer on top of it. Have you considered generating an entire sequence to execute in teststand rather than just one step at a time? Basically converting your test script into a TestStand sequence.

 

Hope this helps,

-Doug

Message 6 of 8
(5,154 Views)

Hi Doug,

 

Thank you very much for the quick response! I will try the proposed fix and will let you know about the results. 

 

In regard to TestStand, we don't use it only as a DLL caller. Actually, we built a generic test environment including .exe/.bat launcher, COM manager, ssh remote controller, test equipment manager, processing manager, analysis manager, and other features.  The advantage of this, is having all the manager now validated, so we can only configure a script file and call any common stuff (exe, dll, com, matlab scripts, more) to test our products. TestStand sequences everything for us.

 

Regards,

C.

0 Kudos
Message 7 of 8
(5,149 Views)

Hi Doug, the proposed workaround resolved my issue. 

 

Thank you very much

C.

0 Kudos
Message 8 of 8
(5,039 Views)