Antoine
Antoine

Reputation: 500

DLL design : the DLL needs to access some of the application functions/data

I have a DLL with a bunch of functions. So far, so good, that's what DLL are for. But, some functions in my DLL need to call functions (or access data) from the application which loaded the DLL.

App.exe :

std::vector<SomeClass> objectsList;
bool foo(void)
{
    ...
}
LoadLibrary( "something.dll" );  

something.dll :

__declspec(dllexport) void someFunction(void)
{
    if ( foo() )
    {
        objectsList[2].someAttr = 1;
    }
}

For what I know, my DLL code in not correct because the DLL cannot know foo or objectsList at linking. So, the only way I see is :

something.dll :

typedef bool fooType(void);
fooType* pFooFunc;
__declspec(dllexport) void setFoo(fooType* fooPtr)
{
    pFooFunc = fooPtr;
}
__declspec(dllexport) void someFunction(void)
{
    if ( (*pFooFunc)() )
    {
        ... _same thing for objectsList_    
    }
}

App.exe :

LoadLibrary( "something.dll" );  
setFoo = GetProcAddress(...);
setFoo(&foo);

Am I right or is there a more elegant way to do that kind of stuff ?
Some solutions here : a DLL need to access symbols of its application But I am still interested in any discussion about this kind of design.

Thanks

Upvotes: 0

Views: 411

Answers (5)

MFH
MFH

Reputation: 1734

Actually a callback is the best way of doing this -> obviously as Oli mentioned a DLL depending on an external implementation may be a sign of a flawed design.

Personally I'd try to have my DLL depend on no external functions -> apart maybe from a callback to register at the executeable…

Upvotes: 0

Ben Voigt
Ben Voigt

Reputation: 283624

Generally you'd pass a pointer to an object with virtual functions. That way you have object-oriented design and callbacks, with a single function call instead of one per exported function.

Upvotes: 1

James Kanze
James Kanze

Reputation: 153899

There are two common solutions: the first is for the DLL to use some sort of callback; the second is to put the functions and data shared between the root and the DLL(s) into a separate DLL of its own.

Upvotes: 2

Alexander Pogrebnyak
Alexander Pogrebnyak

Reputation: 45576

That's a classic design pattern for a callback function.

As long as you document that consumer of your library needs to set a callback and what that callback function is supposed to do, this is fine.

Upvotes: 0

Oliver Charlesworth
Oliver Charlesworth

Reputation: 272457

In general, a callback is an elegant solution.

But it sounds like your DLL is relying on the existence and behaviour of one particular, specific function. If that is the case, then maybe you need to think about whether you have the correct split between your application and your library. Is your library going to be used by more than one application? If yes, then how is this foo() business going to work? If no, then why is it a DLL?

Upvotes: 0

Related Questions