Sign in to follow this  
wicked357

Which one Dynamic Link or Static library?

Recommended Posts

I am working on a simple game engine for a few project to test out certain things, but I don't wanna keep re-typing the code over and over in each or coping all the headers and source files. I don't want to create a template for them, I want to compile them like how DirectX does it or Ogre does it for example. I read on MSDN about Static library (.Lib) and dynamic linked library (DLL), but in both Ogre and DirectX they have both, anyone know how I can go about doing something like this and do I have to create both or just the one. If there is a different kind of tutorial out there besides the MSDN ones I would greatly appreciate any help I can get here. Thank you, btw I am using C++ Win32 and VS2008 Pro.

Share this post


Link to post
Share on other sites
A static library is incorporated in the .exe file when built. So if you want to have multiple exe files using the same static library you might run into lots of problems (if this thing is not impossible). A dynaic library on the other hand can be linked in 2 ways: when you compile the final exe of your probram (compile time) or at runtime (somewhere in your application when you want to invoke a method from a dll you will use LoadLibrary and GetProcAddress , this means that the exe can run widouth the dll present). A exe linked with a dll( when compiled) will report a error message when the dll is missing and you want to run the application.

So when you create your dll library with visual studio the compiler will generate a dll file and a lib file for the same project. Now the lib file will not contain the actual code you wrote;the dll will have that code. The lib is only for the compiler if you wand to bind your dll to some application and you use compile time linking. You can replace the Dll later on but the exe will always need that dll to run. The lib asociated with the dll will only say to the compiler "ok: this is a function and this is the dll that has the implementation"

If you want to use runtime linking you have to use LoadLibrary (this will instruct the windows kernel to load the library into the memory). Once in memory you can get the address of a particular function with getprocaddress. With that addres you can call the code from the dll exactly the same way you would call a function pointer.

Take a note that when you create a dll project and want to use it you have to keep the lib also for easier usage. Still you will have to have the c++ headers of the actual code. ( because using GetProcAddress is a pain in the ass).

A dll or a lib will only contain the implementation so if you have a function void foo() {... do some stuff...} you need to know the definition when you want to use it
so for our example `void foo();` will tell the compiler that the function exists somewhere.
In order to tell the compiler where exactly the implementation is you can use
#pragma comment(lib,"libname.lib"). The compiler will start to look into the libname.lib for the `foo()`. Note that if you have multiple libs with the same name even if you have different implementation the compiler will throw a stupid linker error. if the implementation has not beed found it will say something like `unresolved external symbol void foo()`

#pragma comment(lib,"libname.lib") will work both for a actual lib or a dll ( on the dll you will need to write the lib file that comes with the dll not the dll itself). A dll needs to in the same folder with the exe file or in windows/system32 in order to work.

Hope this helped, sorry for the englesh

Raxvan.

Share this post


Link to post
Share on other sites
The problem I run into is following the directions on MSDN is they only show you how to create one or the other, and when creating them the way MSDN does it only lets you do one or the other I couldn't seem to figure out where to output a DLL and a Lib file in my project. Also I noticed in there guide they use namespace MathFunc or whatever and then you have to do the class name then the function, so if I did something like using namespace MathFunc I would still have to type in classname::function(), but in Ogre you can call using namespace Ogre and be able to use its functions without doing Ogre::classname::function() just a simple function() how is this being done exactly I would find it hard to believe they are not using classes in Ogre and just a bunch of functions and global variables, but I guess I could be wrong if I am can someone explain this to me?

Additional if someone knows how to do what I am asking in Visual Studio can you please give me a step by step break down on how to do this, I have spent hours trying to figure this out and ran through the MSDN guide twice now. If you do here is an example class you can use to explain it to me.


engine.h

class Engine
{
public:
void setInt(int iInt);
int getInt();
private:
int m_iInt;
};

engine.cpp

#include "engine.h"

void Engine::setInt(int iInt)
{
m_iInt = iInt;
}

int Engine::getInt()
{
return m_iInt;
}

Share this post


Link to post
Share on other sites
supose that you have the Project A with the following code:
engine.h provided by you
engine.cpp
You intend to make this a dll so that you ca use it later. Project A (this one) is a dll project (you can do that by new project dll in visual studio. etc) and has only 2 files with your code(engine.h and engine.cpp).

Modify only the first line of the engine.h as this:
class __declspec(dllexport) Engine
{}
...
next compile project A (dll) and in the debug folder of the solution you will get A.dll and A.lib


Project B will use the Dll. The code in main.cpp in project B is the following:
First put A.dll in B/Debug solution folder.

#pragma comment(lib,"A.lib")
// note that you have to write the full path to the A.lib file
// you can write this as a full path to the file ex: "c:/myspace/A.lib"
class __declspec(dllimport) Engine
{
public:
void setInt(int iInt);
int getInt();
private:
int m_iInt;
};
int main()
{
Engine e;
//here you can call methods from e
}




Share this post


Link to post
Share on other sites
Thanks Makaan! Now that I got it working properly, I wonder seeing as how Ogre3D does this to call there members Ogre::function am I to believe they did something like this

namespace Ogre
{
....functions all classless
}

or does anyone have any ideas on this, are they in classes and using a engine pointer, such as static Engine* m_pEngine and use that to reference my class then creating a method like static Engine* getEngine() { return m_pEngine; } so when I am using it in the main function I would do something like this Engine::getEngine()->setInt(9); or Engine::getEngine()->getInt(); What are you thoughts on this, even then it isn't a namespace so I still couldn't do, using namespace Engine; and to getEngine()->setInt(9), etc... I mean I could something like this I suppose instead of putting them in a class.


namespace Engine
{
int m_iInt;
void setInt(int iInt);
int setInt();
}



then the cpp file would pretty much look the same as before. Compiled I would think it would run like Engine::setInt(9) but now I could do using namespace Engine and then just call setInt(9) in my program. Which are the benefits of not using classes in this situation or is there a way to use classes and have the result similar to the classless namespace Engine.

Share this post


Link to post
Share on other sites
Here's how to set up a project to build as a library in Visual Studio:
First, Open the solution file.
Right-Click on the project you want to make into a lib and select properties

Under "General", set the Configuration Type:



To see/change the output file, go to the linker settings:




To link the library in to your source files, you can the do the #pragma thing, but I think it's much cleaner to set up the project to include the libraries since you're using VS already. this way, you can have one solution that has the library project to build and the "game" project that includes that library. Also, all of your libraries are in one place and easy to find/change.



And finally, make sure you set up the directory to find the libraries in:

Share this post


Link to post
Share on other sites
Quote:
Original post by wicked357
Thanks Makaan! Now that I got it working properly, I wonder seeing as how Ogre3D does this to call there members Ogre::function am I to believe they did something like this

namespace Ogre
{
....functions all classless
}

or does anyone have any ideas on this, are they in classes and using a engine pointer, such as static Engine* m_pEngine and use that to reference my class then creating a method like static Engine* getEngine() { return m_pEngine; } so when I am using it in the main function I would do something like this Engine::getEngine()->setInt(9); or Engine::getEngine()->getInt(); What are you thoughts on this, even then it isn't a namespace so I still couldn't do, using namespace Engine; and to getEngine()->setInt(9), etc... I mean I could something like this I suppose instead of putting them in a class.

*** Source Snippet Removed ***

then the cpp file would pretty much look the same as before. Compiled I would think it would run like Engine::setInt(9) but now I could do using namespace Engine and then just call setInt(9) in my program. Which are the benefits of not using classes in this situation or is there a way to use classes and have the result similar to the classless namespace Engine.


At this point you really need to understand the concepts of object oriented programming.
It has nothing to do with they way you exoprt stuff to a dll. A namespace is basically a colection of classes , types , etc used to better encapsulate the code.
When exporting a namespace you don't have to write dllexport in the front of the namespace but insted for every field , variable class inside your namespace. For example:
int __declspec(dllimport) foo(){return 666;} will be exported.
When using a namespace you need to write `using namespace yournamespace;`
As a trick to get rid of the nasty __declspec(dllimport) and __declspec(dllexport) you can do something like this: in a header that is at the base of all files:

#ifdef DLL_LIB
#define DLLMODULE __declspec(dllexport)
#else
#define DLLMODULE __declspec(dllimport)

this way you wirte, insted of __declspec(dllexport) or __declspec(dllimport) every time,DLLMODULE
Just make sure to #define DLL_LIB when you make your dll.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this