Will Perone

Ever wanted to have the ability for people to easily create mod's for games you've programmed? Here's how to do it in Windows utilizing DLL's.

Lets say you have a generic class called Base which has an interface like most typical object systems:
class Base
{
public:
	static char c; // some reference counter or whatever

	int a, b;

	Base()
	{
		c++;
	}

	virtual ~Base()
	{
		...
	}

	virtual void func()= 0;	 // this is an abstract base class
};

char Base::c= 0;

// define an actual type of object with certain behavior
class Derived: public Base
{
public:
	Derived()
	{
		a= 3; b= 4;
	}

	virtual void func()
	{
		a= -1;
	}
};

We want to create a new object that derives from base but has new behavior. We'll call this class Plugin:
class Plugin: public Base
{
public:	
    virtual void func()
	{
		a= 5;
		b= 6;
		c++;
	}
};

What we're gonna want to do is make a new project (console application) for the plugin and set the type/output to DLL. The Plugin class declaration will go in a header file and we will have in the cpp file the following:
extern "C" __declspec(dllexport) Base *CreatePlugin()
{
	return new Plugin();
}

What this does is create an interface to the outside world so that they can call 'CreatePlugin' upon loading the DLL with the plugin. Normally the outside would would have no way of knowing of the existance of Plugin thus this function will return a new Base type that's been allocated internally as a Plugin (yea I know pretty sneaky). Infact, the only thing the outside world will be able to access are functions that have the __declspec(dllexport) in them. the extern "C" is needed because if you are compiling a C++ project the functions get decorated C++ style when their names are generated which (to make a long story short) means Visual Studio is basically gonna put a bunch of garbage around the function name string. Anyway, so after compiling the Plugin to a DLL, how do we actually call CreatePlugin from the game?
#include <windows.h> 

typedef Base *(*CreatePlugin)(); // create a function pointer type that points to CreatePlugin

HINSTANCE hinst= LoadLibrary("whateverdll.dll");
if (hinst)
{
	CreatePlugin ctor= (CreatePlugin)GetProcAddress(hinst, "CreatePlugin");
	Base *test= ctor();
	test->func(); // call the func defined in Plugin, not in Base or Derived
	delete test;  // calls Plugin's dtor 

	FreeLibrary(hinst);
}	

Now that's all well and nice but there's one problem with this so far. What if both the game and the dll need to use the same interface for something; some shared interface. Well that's where static librarys come in. Lets say we have a shared interface like the following:
class SharedInterface
{
public:
	static int func(int a, int b);	
};

Now both Derived and Plugin need to use this guy but Derived is in the exe and Plugin is in the dll. One way or the other you're gonna get link errors when compiling. The answer is to make a new project that compiles to a static library (LIB) and put the SharedInterface in it. Then all you do is link with the shared.lib file in both the exe and dll and you're set; you can now use SharedInterface in both the exe and dll (see accompanying project download).

That's pretty much it. You can optionally do things like search for all DLL's which include a certain function and load them upon loading your application, etc. The code and project for this can be found here
7 Comments
hcrsmeqola 143 116
Hello! Good Site! Thanks you!
arman 6 50
Very clear illustration on this non-trivial issue!
Thanks!
wiegje 2 50
I love you, thanks!
themadme 2011/02/251 56
Nice tutorial
saeed 2011/04/03 Contact Me57 56
hello
thanks for your help
god protect you
wow 2012/10/18 Contact Me0 17
wow
choi hee youl 2014/07/17 Contact Me0 0
oh Thank you :D

<- for private contact