LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

Control callback not found in DLL

Solved!
Go to solution

I am writing a DLL for use in TestStand that uses a couple of panels in a .uir file. The callback functions for the controls are in the source file for the DLL. In another DLL function, I call LoadPanel to bring the panel into memory and I get an error saying it cannot find the callback function for one of the controls on the panel.

 

I am at a loss as to why this is happening. The function prototype is in the header file generated from the .uir. That file is included in my DLL source file and the callback functions for all the controls are also in the DLL source file. Everything compiles fine, it fails at run-time.

 

Am I missing something here? I've used UI stuff in DLLs before and don't recall ever having this problem.

 

I am using CVI 7.1.1 and TestStand 3.1 (Mandated by government customer).

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 1 of 14
(5,684 Views)

Did you bind the main app to the DLL's import library (static load) or are you doing a dynamic load of the DLL?

 

DLL's can be a bear due to search path issues - you can swear you're using a particular DLL yet the dang OS will find an old version of the same DLL somewhere else that you didn't expect.

 

You can try putting the DLL in the same folder as the executable to minimize the liklihood it's finding an old version.

 

Menchar

0 Kudos
Message 2 of 14
(5,682 Views)

I am calling the function from TestStand, it knows explicitly where the DLL is because I told it exactly where to find it. There are also no older versions of the DLL around, this is entirely new and there is only the development version I have been working on today.

 

TestStand is configured to dynamically load the DLL and to unload it when it is done executing that step.

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 3 of 14
(5,679 Views)

Another thought I have is that to export the DLL function you have to decorate it with DLLEXPORT DLLSTDCALL and a callback function needs to be decorated with CVICALLBACK I think it is.  I guess you'd combine these if you want to make the callback an exported DLL function.

 

I've never tried putting a callback in a DLL, I don't know why, really - seems a little too decoupled to me maybe.  If you change the control at all and it affects the callback you've got to go fix it up in a separate module / project.

 

Menchar

0 Kudos
Message 4 of 14
(5,678 Views)

Well, if it's a dyamic load then you're referring to the functions by name or by ordinal and using getprocaddress - I wonder if you're doing it by ordinal and if the ordinal changed on you?  I think depends.exe will show you the function ordinals in the DLL.

 

Menchar

0 Kudos
Message 5 of 14
(5,676 Views)

I am not exporting the callback functions, they are private to the DLL and I really don't want them exported. A higher level function I do export is what calls the LoadPanel function.

 

Having said that, I tried adding DLLEXPORT to the callbacks and that did nothing to help.

 

The purpose of what I am doing is to display some status panels and an operator setup instruction panel with images. This should be very simple to do.

 

 

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 6 of 14
(5,675 Views)

As far as I know, the function call in TestStand is by the function name. But I don't really know what goes on under the hood in TestStand.

 

I've never called any DLL function in any way other than by name in any application I have ever written.

 

But that really doesn't seem to be relevant to me here. The callback is a private function inside the DLL, it should be able to find it and I can't figure out why it does not.

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 7 of 14
(5,674 Views)

I guess I'm wondering then how the callback invoke from a GUI control is able to find the callback function in the DLL if it's not exported?

 

But I'm of no use to you here - I've never tried to put a CVI GUI and its callbacks into a DLL.  Where do you do the RunUserInterface call, in the DLL as well?

 

You can use GetProcAddress using either the function name or the function ordinal.  As you say, this is likely happening behind the scenes in TestStand.

 

Menchar

0 Kudos
Message 8 of 14
(5,671 Views)

How does a DLL know anything about private functions (functions not exported)?

 

I believe it should resolve those symbols at link time when it builds the DLL and should be able to find the callbacks.

 

I know I have done this before and I know it worked. I just have to find a copy of it.

Martin Fredrickson
Test Engineer

Northrop Grumman
Advanced Systems and Products
San Diego, CA 92128
0 Kudos
Message 9 of 14
(5,669 Views)

By direct linkage within the DLL when you build it of course.

 

My curiousity is that how can you be certain that the code that makes the actual callback invocation in response to GUI events is also inside the DLL and has direct access to the callbacks?  You never actually see this code - it's behind the scenes when the GUI is loaded and you've done a RunUserInterface call.

 

I think it's at LoadPanel time where you get the runtime error if there's a reference to a callback function that the CVI runtime system can't find.  The CVI RTE must do dynamic binding of the callback functions referenced in the .uir file to a function table within the executable or DLL module.

 

Well, good luck, I'll be curious what the answer is - I suspect in the morning when one of the NI folks sees your post you'll get an answer.  Sometimes a NI  employee in Europe will see it during the night and post a reply.

 

 

0 Kudos
Message 10 of 14
(5,666 Views)