Question about Dlls with C++

So I’m writing a system where I need to explicitly load (via LoadLibrary, GetProcAddress, ect) a dynamic library into my project (which is an executable). I’ve been able to do this successfully, however, how can I make it so that the dll can use all the functions present in the executable environment?

When I code my dll, how can I use functions and classes that I’ve created inside my executable without compiling them into the dll (which would result in essentially two copies, unnecessarily).

So I can call say computeAIPath() inside my dll, however its definition resides within the executable which will be dynamically loading the dll. Without the executable’s definition, the dll cannot use the computeAIPath() function.

Here’s somthing similar to the setup I’m using: (I’m not using this code at all, just an example)

mydll.h

extern "C" {
EXPORT int countChars (char* chars);
}

mydll.cpp

#include "mydll.h"

int countChars (char* chars)
{
	int count = 0;
	while (chars[count] != '\0')
	{
		count++;
	}
	return count;
}

compiles to mydll.dll

myapp.h

#include <iostream>
//assume there are a bunch of includes, declarations ect

myapp.cpp

#include "myapp.h"

typedef int (*myfunc)(char* str)

int main()
{
	HINSTANCE hDll;
	hDll = LoadLibrary(L"C:\\mydll.dll");

	if (hDll)
	{
		myfunc countChars;
		countChars = (myfunc)GetProcAddress(hDll,"countChars");

		if (countChars)
		{
			//code...
		}
		else
		{
			cout<<GetLastError()<<endl;
		}
	}
	else
	{
		cout<<GetLastError()<<endl;
	}
        return 0;
}

Now say I had a function computeAIPath() declared in myapp.h and defined in myapp.cpp, how would I use that function in mydll.h/cpp?

This information seems difficult to extract from the web, so some help would be appreciated.

I believe you can do this via the module handle returned by GetModuleHandle(). Pass this handle into GetProcAddress(). I’ve never tried this myself, though; though I’m pretty sure it should work. Even if it does, though, it’s not portable, if that’s a concern of yours.

Another approach is to explicitly pass a pointer to your function into the dll. Then the dll can call that function pointer.

A third approach is to put your common code into a second dll, and LoadLibrary() that dll into both your executable and the first dll.

David

Thanks for the response.

For reasons of practicality, I don’t think the first two methods you mentioned would be viable, they seem a bit untidy. However, I like the third option you mentioned, however it may cause the dll to load into memory multiple times.

I’ve found yet another way to do it which I think works best, but I’m not sure if it is the industry’s standard way of doing things, I’m not really sure.

Here’s what seems to work:

myapp.h

...
#define PUB_API __declspec(dllexport)
...
...
PUB_API void myfunc(int arg);
...

When I compile that, MSVC automatically creates a static library file for me to link against (.lib)

mydll.h

...
#define IMPORT extern __declspec(dllimport)
#define PUB_API extern "C" __declspec(dllexport)
...
IMPORT void myfunc(int arg);
...

I’m using extern “C” here to export because I’m using GetProcAddress to retrieve it which requires no name mangling, i.e. because it is being loaded dynamically by the executable rather than being linked at compile time like the dll’s imports are.

I should be able to combine all the declarations into a single header file to be included by the dlls and the exe and use a macro to determine whether the functions are being exported or imported.

The second isn’t untidy at all – it’s “dependency injection”, which is a useful way of keeping code tidy even without DLL stuff motivating it. It’s also pretty standard – a lot of middleware I’ve seen uses it to allow custom memory allocation routines and the like. For more than a couple of function callbacks, of course, they wouldn’t be individual function callbacks, but rather a pointer to an abstract class containing the methods.

I’m afraid I don’t understand much about that, could you give a brief example of how it works in this situation? Are you saying I can create a pointer to a class defined by the external exe and use it inside the dll?

I think the way I sugjested is the way it is done when you are creating a library for say python or lua correct? When you include the python/lua headers you must compile against the correct lib files. That is where I got my method from, though I’m not sure they are the same.

In a shared header:

class ProgramInterface {
public:
    virtual funcA() = 0;
    virtual funcB() = 0;
    // etc...
};

In the DLL:

DLLInitFunc(ProgramInterface* pi) {
    g_pi = pi;
}

void doSomethingRequiringProgramAccess() {
    g_pi->funcB();
}

In the executable:

class ProgramInterfaceImpl : public ProgramInterface {
public:
    virtual funcA() { doSomething(); }
    virtual funcB() { doSomethingElse; }
};

// and later...

DLLInitFunc(new ProgramInterface());

See how it goes? When the program initializes the DLL, it passes in an “ambassador” interface of sorts, that handles all the things that the DLL will need from the program. The DLL uses that interface’s facilities (which here are simply functions, but could take a more complex form if needed) to do whatever it needs to do to the program. The scope of the interface defines the limits of what the DLL is allowed to do, maximizing tidiness.