我有一堆带有许多功能的DLL。到目前为止,非常好,这就是DLL的用途。 但是,我的DLL中的一些函数需要从加载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;
}
}
据我所知,我的DLL代码不正确,因为DLL在链接时无法知道foo
或objectsList
。所以,我看到的唯一方法是:
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);
我是对的还是有更优雅的方式来做这种事情? 这里有一些解决方案:a DLL need to access symbols of its application 但我仍然对任何有关这种设计的讨论感兴趣。
由于
答案 0 :(得分:2)
有两种常见的解决方案:第一种是DLL使用 某种回调;第二是把功能和 将根和DLL之间共享的数据转换为单独的DLL 它自己的。
答案 1 :(得分:1)
通常,您会将指针传递给具有虚函数的对象。这样,您就可以进行面向对象的设计和回调,只需一个函数调用,而不是每个导出函数调用一次。
答案 2 :(得分:0)
通常,回调 是一个优雅的解决方案。
但听起来你的DLL依赖于一个特定的特定功能的存在和行为。如果是这种情况,那么您可能需要考虑是否在应用程序和库之间进行了正确的拆分。您的图书馆是否会被多个应用程序使用?如果是,那么这个foo()
业务将如何运作?如果不是,那为什么它是一个DLL?
答案 3 :(得分:0)
这是回调函数的经典设计模式。
只要您记录库的使用者需要设置回调以及该回调函数应该做什么,这就没问题。
答案 4 :(得分:0)
实际上回调是这样做的最佳方式 - &gt;显然,正如Oli提到的,依赖于外部实现的DLL可能是设计有缺陷的标志。
我个人试图让我的DLL依赖于没有外部功能 - &gt;除了回调注册可执行...