12-07-2021 05:46 PM
I have tried this both on 2016 and 2020 CVI Full Dev applications. Same result. When I start typing functions included in the winscard.h the program is happy to allow me to use the autofill. This tells me that it sees the dll/lib/.h files so it 'should work' but it doesn't or there is more to the many examples online that I have tried that eludes me. Researching others with similar errors usually resulted in a missing dll or lib file. If these are included with the CVI full dev software, I would think this is not the case here? Below is a small clip of my code.
The exact error I am getting is :
error: Undefined symbol '_SCardEstablishContext@16' referenced in "c:\...CardReader.obj".
#include <windows.h>
#include <ansi_c.h>
#include <cvirte.h>
#include <userint.h>
#include <utility.h>
#include <winscard.h>
int main()
{
long lResponse;
SCARDCONTEXT hContext;
lResponse = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
lResponse = SCardReleaseContext(hContext);
return 0;
}
Solved! Go to Solution.
12-07-2021 06:21 PM
This is a Windows API function. So you search on MSDN for it and get here: https://docs.microsoft.com/en-us/windows/win32/api/winscard/nf-winscard-scardestablishcontext
At the end of that page you see what is the minimum OS, which header declares the function. Which DLL implements it and which import library contains the import stub for it.
Add the name for the import library to the linker options in your project.
12-08-2021 12:56 PM - edited 12-08-2021 12:57 PM
If I am understanding what you wrote, I believe I already linked it to my project when I added "#include <winscard.h>" to the header of my program. If I start to type SCardEstablishContext.. it provides me with the autofill information. This leads me to believe that the program and CVI have "knowledge" that the .h, dll and lib are somewhere. I did download the most recent SDK from MSDN and I still get the same exact error.
12-08-2021 02:38 PM - edited 12-08-2021 02:41 PM
No you understood that wrong. A C compiler is a two step process.
First you have the compiler which reads the C source file puts it through the pre processor to generate the actual source code (in the past the C pre-processor was a seperate program so it was really a three step process then). The C compiler creates from each source file an object file that contains the compiled binary code and informations about what functions and variables it can provide itself and what it needs as external reference for its own functions.
After that there is the linker, this linker collects the different object modules and creates the final executable or DLL or sometimes also a link library (which is a collection of object files to use later in another linker step).
Adding an #include <winscard.h> file to your source code simply lets the preprocessor inline everything that is contained in winscard.h into the source file so the compiler knows how the function prototypes and constant and datatypes are defined. The compiler uses that information to prepare the callsites of functions to push the correct amount of parameters and their correct datatype onto the stack, but only puts a reference into the code to tell the linker "Here you need to add a call to function xyz()". It does not contain any information as to from where this xyz() function needs to be taken.
The linker then gets called with ALL the object modules (and the possible libraries that contain multiple object modules) as well as a list of directories it can search for these object modules and libraries. That part has nothing to do with the include you added to the source code and there is no direct link that could tell the linker that "winscard.h" means there needs to be an import from Winscard.lib. In this particular case you could argue that the name is the same and only the ending is different, so WTF. But this name matching is in reality an exception. Most often the name of the relevant header has only little to do with the actual compiled library. Because of that C compilers don't even try to attempt to make such associations but simply require that you as programmer do the correct #include in the source code AND add the correct link libraries to the linker parameters too.
You can keep downloading SDK for Windows 11, 12 and 13 and this will not change. C compilers simply do not work as you would want them to and you need to go into your CVI project settings and add any additional library you want to link into your final build product, if you like it or not.
12-21-2021 04:03 PM
I got caught up in thinking that because the compiler knew about the various functions and identifiers, the DLL was linked already. As you pointed out (and I misunderstood), it needed to be added to my project. Once linked, things progressively started working. I appreciated the help Rolf!!