LabWindows/CVI

cancel
Showing results for 
Search instead for 
Did you mean: 

"undefined symbol" error while using a custom instrument driver

Hello all, I'm facing a problem related to instrument driver creation.

I want to pack a part of my code to a .FP to be able to reuse it in other applications of mine. This part of code includes calls to Windows API and a third party dll. I have included both windows.h and the include for the dll in the header file for the instrument. I developed the source code and next a little application that simply calls one function to test the result of my work, but I get some 'undefined symbol' errores while linking the test application with the instrument. The instrument header file is included in program source file.

 

Situation is as follows:

  • I can run the test application if I include the source file for the instrument directly in the project (without loading the instrument)
  • I created a static library and can have the test program up and running if directly including the library in the project (again without the .fp file)
  • I get linker errors when trying to use the instrument I created based on the same code, both when including the instrument at source code level and when including at library level. Adding the .fp to the project makes no difference

 

Linker errors are all related to WinSDK and third-party dll functions.

 

Question is: where and how I have to declare the symbols apart including the appropriate .h files in the instrument header file?



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 1 of 16
(4,864 Views)

Roberto,

 

I haven't used an fp for a while now, but the last time I did was for a situation very similar to yours, where it was calling third-party dlls and Windows functions. (I used CVI 7.0) I did not experience any of your problems, though. I developed the instrument code as a dll and it was built as usual, with the third partly import libraries explicitly inlcuded in its project. The deliverable files (to other projects requiring to use the instrument) were the fp, the header, the dll and its import library.

 

Would this dll approach work for your situation?

 

JR

0 Kudos
Message 2 of 16
(4,862 Views)

Hi JR,

 

I would like not to distribute an additional DLL and have the code included in the executable instead.

 

Nevertheless, I made a fast try switching the target type to DLL, including the import library for the thirtd party dll in the project and creating the library: the linker now complains only about WinSDK functions  Smiley Sad

 

The strange thing is that this same code perfectly works while included at source level in target application project!

 

 

I don't understant what's different between these two scenarios...



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 3 of 16
(4,862 Views)

Work in progress...

 

Of course I was missing the relevant SDK lib...  Now the DLL compiles and links ok. Smiley Happy

 

 

It remains unknown why I cannot link the project  if including the instrument at code or lib level: the import libraries for both third party dll and SDK calls are already included in the project, so... why? Smiley Surprised



Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 4 of 16
(4,856 Views)

I have encountered a similar situation when using MS Visual Studio. I tried to generate a static library which incorporated other third-party (import) libraries but the final link stage of the end application still wanted to reference the third party libraries. Apparantly it is possible to configure Visual Studio so that the intermediate static .lib file contains all the relevant information (and so would not require the final application to need all the libraries) but this is not standard behaviour and I never bothered to investigate further.

 

It seems that the CVI linker is proceeding along the same lines, but I'm less confident that its behaviour can be altered. We need to wait for Luis to log on Smiley Tongue

 

JR

0 Kudos
Message 5 of 16
(4,842 Views)

Being waited on to log on... how flattering Smiley Tongue

 

I wish I had a simple and obvious solution, but I don't.

 

The problem in this case is that, whereas DLLs (via their import libraries) carry no additional build-time dependencies to their clients, that is not the case with object files and static libraries: any project that uses those .obj and .lib files must satisfy all of their dependencies when that project builds.

 

There is a mechanism, with .fp files, to advertise such dependencies to the clients of the .fp, and that is the auto-load list (Edit>>FP Auto-Load List, in the function tree editor). The caveat, however, is that these indirect dependencies must have a companion .fp that you can add to this list. And in your case, you don't have one. So the only solution I can think of is for you to create a very thin wrapper module where you would wrap all of the SDK functions that you need, then create a basic .fp for this wrapper -- you can do this semi-automatically, from the header file (Options>>Generate Function Tree) -- and then add this .fp to the auto-load list of your primary .fp. And then you'll probably have to create a second .fp wrapper for your other dependency (a non-SDK third-party DLL?).

 

Once you have declared the dependency chain for this .fp, you should then be able to use it on any test application and CVI should know to link in these additional static libraries whenever it builds the test application.

 

If you choose to go this route, you'll probably have to deal with a bunch of non-standard data types in the parameters of the SDK functions. I don't remember if these are automatically added to the .fp when you create it from the header file. If not, all you need to do is add them to the .fp  later (Options>>Data Types, from the function panel editor). Don't worry about providing the definitions for these data types. They're not necessary. You just need to make sure that their names are in the list.

 

Luis

Message Edited by LuisG on 05-19-2010 10:43 AM
0 Kudos
Message 6 of 16
(4,822 Views)

Actually, as I think about this some more, I don't think my suggestion would work either. It would probably add another level of indirection but it would just push the problem down to the second level. Let me think about this some more, and actually do a couple of tests, and then I'll post an update.

 

Luis

0 Kudos
Message 7 of 16
(4,815 Views)

Hello Luis, thanks for giving this a trial. Smiley Happy

 

Based on your words I suppose I will split down the instrument and proceed step by step:

 

  • A first instrument with my functions only: I had no errors on these functions so I suppose this will go on immediately
  • A second instrument for the third party dll: I'll try to create the wrapper to the dll and have the instrument built on top of the wrapper. I hope I have no problems in doing so
  • A third instrument with the wrapper to SDK function, if and when you can explain how to address linking problem. If not I'll continue directly calling these functions from the code as I have done till now.

 

This approach should permit me to have part of the job completed and reusable in my applications. As far as other steps are completed, I'll proceed integrating them in my actual code; in the meanwhile I'll continue directly coding these functions as I've done till now.

 

 

I've always been a fan of "the simpler the better" Smiley Wink

Message Edited by Roberto Bozzolo on 05-19-2010 06:18 PM


Proud to use LW/CVI from 3.1 on.

My contributions to the Developer Community
________________________________________
If I have helped you, why not giving me a kudos?
0 Kudos
Message 8 of 16
(4,794 Views)

Hi Roberto,

 

Did you notice my second post? I started having second thoughts about my suggestion almost as soon as I posted it. I've now done the actual test and confirmed my suspicions. Doing the wrappers won't really help at all, unfortunately, since the SDK dependency will still percolate throughout the chain. I don't know what I was thinking, really...

 

The only way to resolve this is to have a DLL. Either that, or document the fact that in order to use this .fp, client projects must also include a couple of additional libs.

 

There's only one thing about this that still doesn't make sense to me, and that is the fact that you didn't get a link error when you added the source of the .fp to the project. That shouldn't make any difference. The test application project would still need to include the SDK lib, regardless of whether you're using the source file or the .fp.

 

Luis

 

0 Kudos
Message 9 of 16
(4,785 Views)

LuisG wrote:

 

There's only one thing about this that still doesn't make sense to me, and that is the fact that you didn't get a link error when you added the source of the .fp to the project. That shouldn't make any difference. The test application project would still need to include the SDK lib, regardless of whether you're using the source file or the .fp.


That might be caused by link order. If the linker is a single pass linker and library/object file "a" depends on library/object file "b" you have to link "a" first  and then "b". If you link vice versa you will get undefined symbols. If you include the source the link order is changed implicitely and you get it right then. Unfortunalety these details are hidden by the IDE.

Message 10 of 16
(4,759 Views)