05-19-2010 02:34 AM
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:
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?
05-19-2010 03:38 AM
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
05-19-2010 04:07 AM
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 ![]()
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...
05-19-2010 04:20 AM
Work in progress...
Of course I was missing the relevant SDK lib... Now the DLL compiles and links ok. ![]()
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? ![]()
05-19-2010 06:54 AM
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 ![]()
JR
05-19-2010 10:34 AM - edited 05-19-2010 10:43 AM
Being waited on to log on... how flattering ![]()
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
05-19-2010 10:44 AM
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
05-19-2010 11:17 AM - edited 05-19-2010 11:18 AM
Hello Luis, thanks for giving this a trial. ![]()
Based on your words I suppose I will split down the instrument and proceed step by step:
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" ![]()
05-19-2010 12:45 PM
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
05-20-2010 12:02 AM
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.