Creating a dll which links to another dll (MSVS2008 C++)
I am currently creating my own framework in C++ (MSVS 2008) which exports a dll with a bunch of functions for a user of my framework to use/call. In the beginning, when my project was still small, all worked fine. I compiled my project. A MyFramework.dll and MyFramework.lib were spit out. I pretended to be a user; put the MyFramework.dll file in my new VS project's Debug folder, put the MyFramework.lib and MyFramework.h file in my project folder, #include-d MyFramework.h in my code and voilá, I could call the (still simple) framework functions from within my new project.
But now I have expanded my framework. It now uses an external dll of its own (let me call it Graphics.dll) and included it in the same way (.dll in Debug folder, .lib/.h in project folder, #include Graphics.h in code).
The problem is that when I nów create MyFramework.dll/MyFramework.lib, include it in my new project and build, the linker complains about not being able to include Graphics.h, which obviously was included in MyFramework.dll somewhere.
So my question. I would like the user of MyFramework.dll to solely have to include the MyFramework.* files in their project and not have the need to copy/paste all external libraries I decide to use in MyFramework. How can I accomplish this? I took a look at this thread. It says something about adding an existing item and pressing the s开发者_JAVA百科mall arrow next to the "Add" button, but...the arrow is nonexistent in my version of MSVS...
Help is very much appreciated.
Kind regards W. Spek
What is happening is the user is including one of your library's header files. This file is then including "graphics.h". If you don't want to require your users to have access to this file you must hide it from your libraries interface.
That is your library must have public api header files and private implementation header files. Your user only includes the public api header files, these do not include any 3rd party or private include files. When these files reference private types or 3rd party types, they can only use pointers or references, these are forward declared. This enables the private part of a class to use private library code and 3rd party types.
The chances are using the Pimpl Idiom will fix this for you.
"The problem is that when I nów create MyFramework.dll/MyFramework.lib, include it in my new project and build, the linker complains about not being able to include Graphics.h, which obviously was included in MyFramework.dll somewhere."
Have you put the path to the header file? The compiler is reporting that the header file is not in the same directory as the cpp file being converted and its not listed in the additional include directories either.
Go to Project->Properties then select C/C++
The first option you'll see is "Additional Include Directories". You need to put the path to your header Graphics.h in there along with any other paths required all semi-colon seperated. The project I have open at the mo has, for example: "../AudioLibrary;../CoreLibrary;"
Edit: From your comments to Mark's post you say you want to embed the Graphics.DLL in your DLL. My answer is as follows:
If you don't have the source code to the Graphics.dll then you have a problem. What you are asking IS possible but VERY complex to do. Basically you can't use LoadLibrary. You will be forced to write your own for of LoadLibaray and GetProcAddress that will look at the embedded DLL and not try and find it on disk ... Its doable but you are going to need to do a lot of reading on the Portable Executable (PE) file structure.
If you don't want to require the user to have or include Graphics.h, one way around that is to use LoadLibrary
to dynamically load Graphics.dll at runtime.
This will mean that the user will be able to compile against MyFramework without Graphics.dll being available, so it might be wise to do some kind of error reporting if LoadLibrary fails.
Once you have successfully called LoadLibrary
on Graphics.dll, you'll need to manually import each function (and its signature) using GetProcAddress
-- this will actually give you function pointers. How you store the function pointers is up to you; I generally prefer to have wrap a class around the imported functions but there's nothing stopping you from keeping the function pointers in the global scope.
As mentioned in the comments, if you don't want to distribute Graphics.dll at all, it will need to be a static library (i.e. "built in" to MyFramework.dll). If you do want to distribute Graphics.dll (so the user can use Graphics.dll without MyFramework.dll), then the above approach remains the better option. Really, the above approach assumes you are distributing Graphics.dll with MyFramework.dll, but that the user may not necessarily have Graphics.h available.
精彩评论