Linking an external DLL
-
Tuesday, February 23, 2010 7:56 PMUsing Visual C++ Express 2008 I built a DLL according to the example http://msdn.microsoft.com/en-us/library/ms235636.aspx . Works great -- as long as the DLL and calling program are projects within the same solution.
Now I want to link my DLL into a WIN32 Console Application project in another solution. Things break down when I try to Add New Reference… from Project menu, References…, Property Pages dialog box, Common Properties node, Framework and References. My DLL does not appear in the Add Reference dialog. Adding a Reference Search Path to the DLL location doesn't seem to help.
Two problems result. First the compiler cannot find the DLL header. If I cheat my way past that by hardcoding the header path in the #include statement, then the linker gives "error LNK2019: unresolved external symbol" for symbols defined in the DLL.
How can I link an externally defined DLL into a Visual C++ Express 2008 solution?
Thanks!- Edited by BoCoMo Boy Wednesday, February 24, 2010 12:30 AM
Answers
-
Tuesday, February 23, 2010 8:39 PM
Since you are using a native DLL then Add New Reference will not work. The reason why this example works is because the DLL and the executable are part of the same solution. This is obviously not the case when you are using it from an outside source.
First, "Cheating" your way past the include isn't really cheating. There are pleanty of ways to get the compiler to see the include. Mostly they work through Additional Include Directory (/I). This will tell the compiler to look in a particular directory for the includes, so it isn't really cheating.
You can find this option under Project Properties->Configuration Properties->C/C++->General
Once your project can find the header then it is only half of the battle. You need to tell the linker where to find your compiled code. If you look, there is nothing telling your project that it is in a certain DLL. So you compile and it comes to linking you end up with unresolved symbols. This is actually expected. Lets face it, if you packed all of your belongings into boxes without marking them, someone came and asked you for something then it would be hard to turn around and say, "it is in that one." What you are missing here is the way to point the program to the correct "box". When a DLL is part of a solution then it does it automagically through the Link Dependant Libraries. (This is the whole add reference bit, so this is why it will only work when they are inside the same solution.) If what you want to link to is not inside the solution then you have to start looking for certain files. When you build the DLL you should notice a file with the .lib extension. This is your label. If you add this to your project as a linker input then your project will find the symbols defined inside your DLL and compile properly.
To do this, go to Project Properties->Configuration Properties->Linker->Input and look for Additional dependencies. If you put the name of the .lib file (including the extension) here then it will try to link with it. You should also put the .lib file somewhere the linker can find it, either in the same directory as the project file or add a directory to Additional Library Directories under General.
I would also suggest you look at http://msdn.microsoft.com/en-us/library/1ez7dh12.aspx, especially Linking an Executable to a DLL.
Visit my (not very good) blog at http://c2kblog.blogspot.com/- Marked As Answer by BoCoMo Boy Wednesday, February 24, 2010 12:59 PM
All Replies
-
Tuesday, February 23, 2010 8:39 PM
Since you are using a native DLL then Add New Reference will not work. The reason why this example works is because the DLL and the executable are part of the same solution. This is obviously not the case when you are using it from an outside source.
First, "Cheating" your way past the include isn't really cheating. There are pleanty of ways to get the compiler to see the include. Mostly they work through Additional Include Directory (/I). This will tell the compiler to look in a particular directory for the includes, so it isn't really cheating.
You can find this option under Project Properties->Configuration Properties->C/C++->General
Once your project can find the header then it is only half of the battle. You need to tell the linker where to find your compiled code. If you look, there is nothing telling your project that it is in a certain DLL. So you compile and it comes to linking you end up with unresolved symbols. This is actually expected. Lets face it, if you packed all of your belongings into boxes without marking them, someone came and asked you for something then it would be hard to turn around and say, "it is in that one." What you are missing here is the way to point the program to the correct "box". When a DLL is part of a solution then it does it automagically through the Link Dependant Libraries. (This is the whole add reference bit, so this is why it will only work when they are inside the same solution.) If what you want to link to is not inside the solution then you have to start looking for certain files. When you build the DLL you should notice a file with the .lib extension. This is your label. If you add this to your project as a linker input then your project will find the symbols defined inside your DLL and compile properly.
To do this, go to Project Properties->Configuration Properties->Linker->Input and look for Additional dependencies. If you put the name of the .lib file (including the extension) here then it will try to link with it. You should also put the .lib file somewhere the linker can find it, either in the same directory as the project file or add a directory to Additional Library Directories under General.
I would also suggest you look at http://msdn.microsoft.com/en-us/library/1ez7dh12.aspx, especially Linking an Executable to a DLL.
Visit my (not very good) blog at http://c2kblog.blogspot.com/- Marked As Answer by BoCoMo Boy Wednesday, February 24, 2010 12:59 PM
-
Wednesday, February 24, 2010 12:59 PMGreat! After adding the link options suggested, the project builds.
Now when I run it from Visual Studio, I get a runtime error saying my .dll file was not found. I'm guessing that I need to set the PATH variable, but how do I do this for running from within Visual Studio?
Thanks! -
Wednesday, February 24, 2010 3:15 PMJust copy the dll into the same directory as the exe. The loader will look there.
Visit my (not very good) blog at http://c2kblog.blogspot.com/ -
Thursday, February 25, 2010 7:24 PM
The answer to setting the PATH from Visual Studio is right in the example:
on the Property Pages dialog box, expand the Configuration Properties node and select Debugging. Next to Environment, type the following: PATH=<path_of_.dll_file>
My problem was my <path_of_.dll_file> was double-quoted (as depicted when a folder is dragged into a Command Prompt window). With the quotes removed, Visual Studio finds the DLL at runtime.
Thanks for the help! -
Saturday, February 27, 2010 8:08 AMThanks for the great help, but I'm kinda confused, is it Absoltely necessary to have the header file in order to be able to use the functionality of a DLL file? isn't there a way to use it just with the *.ddl and the *.lib files?
Thank you in advance :) -
Saturday, February 27, 2010 4:39 PMFrom a native application you can get away with not having the header file, but how do you know what is defined in the DLL and how it is defined.
You could use dumpbin to get what, but that wont tell you how. If you are wondering why the how is so important, then lets take kernel32 for example.
If you run dumpbin on kernel32 to get what it exports you will get for example
145 8F 000122FB CreateFileW
So you know that it exports a symbol CreateFileW. So what is it's calling convention (well that should be easy since Win32 is always __stdcall), the return type, the parameters. The DLL and lib file just doesn't give you that information. If it was a C++ mangled name then you are better off since there are ways to work out what it is, but you will mostly find C exports coming from a DLL since they are more cross compiler friendly.
These things usually work together. The DLL to contain the code, the lib to resovle the dependencies and the header to give the function definitions. Without the lib file it is easy to fix, but without the header you have to know indepth things about the DLL to work with it.
Visit my (not very good) blog at http://c2kblog.blogspot.com/