dll与visual studio之间的循环依赖关系

Kri*_*ans 10 c++ dll circular-dependency

我有两个函数之间的循环依赖.我希望这些函数中的每一个都驻留在它自己的dll中.是否可以使用visual studio构建它?

foo(int i)
{
   if (i > 0)
      bar(i -i);
}
Run Code Online (Sandbox Code Playgroud)

- >应该编译成foo.dll

bar(int i)
{
   if (i > 0)
      foo(i - i);
}
Run Code Online (Sandbox Code Playgroud)

- >应该编译成bar.dll

我在visual studio中创建了两个项目,一个用于foo,一个用于bar.通过玩'参考'并编译几次,我设法获得了我想要的dll.我想知道视觉工作室是否提供了一种以干净的方式做到这一点的方法.

如果foo改变了,bar不需要重新编译,因为我只依赖于bar的签名,而不是bar的实现.如果两个dll都有lib存在,我可以将新功能重新编译为两者中的任何一个,整个系统仍然有效.

我尝试这个的原因是我有一个循环依赖的遗留系统,目前静态链接.出于各种原因,我们想要转向dll.我们不想等到清理所有循环依赖项.我正在考虑解决方案,并在linux上用gcc尝试了一些东西,在那里可以做我建议的.因此,您可以拥有两个彼此依赖的共享库,并且可以彼此独立构建.

我知道循环依赖并不是一件好事,但这不是我想要的讨论.

Dan*_*ker 11

它在类Unix系统上工作的原因是因为它们在加载时执行实际的链接解析.共享库在将其加载到进程中之前不知道其函数定义将来自何处.这方面的缺点是你也不知道.库可以在任何其他库(甚至是首先启动该过程的主二进制文件)中查找和调​​用函数.默认情况下,还会导出共享库中的所有内容.

Windows根本不起作用.仅导出显式导出的内容,并且必须在库链接时解析所有导入,此时将确定将为每个导入函数提供的DLL的标识.这需要导入库链接.

但是,您可以(通过一些额外的工作)解决这个问题.使用LoadLibrary打开任何你喜欢的DLL,然后用GetProcAddress定位要调用的函数.这样,没有限制.但正常方法的限制是有原因的.

当您想要从静态库转换为DLL时,听起来您假设您应该将每个静态库转换为DLL.那不是你唯一的选择.为什么不将代码识别为一个独立的模块,适合没有圆度的分层设计,就开始将代码转移到DLL中?这样你就可以开始这个过程,但仍然可以一次攻击它.


ann*_*ata 7

我非常同情你的情况(正如你的编辑所澄清的那样),但作为一个坚定的信徒做正确的事情,而不是现在有效的事情,如果有任何可能性,我认为你需要重构这些项目.

解决问题而不是症状.


小智 5

可以将带有.EXP文件的LIB实用程序用于"引导"(没有先前.LIB文件的构建)一组带有循环引用的DLL,例如这个.有关详细信息,请参阅MSDN文章

我同意上面的其他人一样,应该通过修改设计来避免这种情况.


Rob*_*use 0

不可能做得干净。因为它们都是相互依赖的,如果A改变了,那么B就必须重新编译。因为B被重新编译了,它发生了变化,A需要重新编译等等。

这是循环依赖不好的部分原因,无论您是否愿意,都不能将其排除在讨论之外。