circular dependencies between dlls with visual studio(dll 与 Visual Studio 之间的循环依赖)
问题描述
我在两个函数之间存在循环依赖.我希望这些函数中的每一个都驻留在自己的 dll 中.是否可以使用 Visual Studio 来构建它?
I have a circular dependency between two functions. I would like each of these functions to reside in its own dll. Is it possible to build this with visual studio?
foo(int i)
{
if (i > 0)
bar(i -i);
}
-> 应该编译成 foo.dll
-> should compile into foo.dll
bar(int i)
{
if (i > 0)
foo(i - i);
}
-> 应该编译成 bar.dll
-> should compile into bar.dll
我在 Visual Studio 中创建了两个项目,一个用于 foo,一个用于 bar.通过使用参考"并编译几次,我设法获得了我想要的 dll.但是,我想知道 Visual Studio 是否提供了一种以干净的方式执行此操作的方法.
I have created two projects in visual studio, one for foo and one for bar. By playing with the 'References' and compiling a few times, I managed to get the dll's that I want. I would like to know however whether visual studio offers a way to do this in a clean way.
如果foo改变了,bar不需要重新编译,因为我只依赖bar的签名,不依赖bar的实现.如果两个 dll 都存在 lib,我可以将新功能重新编译到两者中的任何一个中,并且整个系统仍然可以工作.
If foo changes, bar does not need to be recompiled, because I only depend on the signature of bar, not on the implementation of bar. If both dll's have the lib present, I can recompile new functionality into either of the two and the whole system still works.
我尝试这样做的原因是我有一个具有循环依赖关系的遗留系统,它目前是静态链接的.由于各种原因,我们想转向 dll.我们不想等到我们清理所有循环依赖.我正在考虑解决方案,并在 linux 上使用 gcc 尝试了一些东西,并且可以按照我的建议进行操作.因此,您可以拥有两个相互依赖且可以相互独立构建的共享库.
The reason I am trying this is that I have a legacy system with circular dependencies, which is currently statically linked. We want to move towards dll's for various reasons. We don't want to wait until we clean up all the circular dependencies. I was thinking about solutions and tried out some things with gcc on linux and there it is possible to do what I suggest. So you can have two shared libraries that depend on each other and can be built independent of each other.
我知道循环依赖不是一件好事,但这不是我想要的讨论.
I know that circular dependencies are not a good thing to have, but that is not the discussion I want to have.
推荐答案
它在类 Unix 系统上工作的原因是因为它们在加载时执行实际的链接解析.共享库在加载到进程之前不知道它的函数定义来自哪里.这样做的缺点是你也不知道.库可以在任何其他库(甚至首先启动进程的主二进制文件)中查找和调用函数.默认情况下,共享库中的所有内容都会导出.
The reason it works on Unix-like systems is because they perform actual linking resolution at load time. A shared library does not know where its function definition will come from until it's loaded into a process. The downside of this is that you don't know either. A library can find and call functions in any other library (or even the main binary that launched the process in the first place). Also by default everything in a shared library is exported.
Windows 根本不能那样工作.仅导出显式导出的内容,并且所有导入都必须在库链接时解析,此时将确定将提供每个导入函数的 DLL 的身份.这需要一个导入库来链接.
Windows doesn't work like that at all. Only explicitly exported things are exported, and all imports must be resolved at library link-time, by which point the identity of the DLL that will supply each imported function has been determined. This requires an import library to link against.
但是,您可以(通过一些额外的工作)解决这个问题.使用LoadLibrary
打开任何你喜欢的DLL,然后使用GetProcAddress
来定位你想要调用的函数.这样,就没有任何限制.但是正常方法的限制是有原因的.
However, you can (with some extra work) get around this. Use LoadLibrary
to open any DLL you like, and then use GetProcAddress
to locate the functions you want to call. This way, there are no restrictions. But the restrictions in the normal method are there for a reason.
当您想从静态库转换为 DLL 时,听起来好像您假设您应该将每个静态库都变成一个 DLL.那不是你唯一的选择.为什么不开始将代码移动到 DLL 中,仅当您将其识别为适合分层设计且没有循环的自包含模块时呢?这样你就可以现在开始这个过程,但仍然一次攻击它.
As you want to transition from static libraries to DLLs, it sounds like you're assuming that you should make each static library into a DLL. That's not your only option. Why not start moving code into DLLs only when you identify it as a self-contained module that fits into a layered design with no circularity? That way you can begin the process now but still attack it a piece at a time.
这篇关于dll 与 Visual Studio 之间的循环依赖的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!
本文标题为:dll 与 Visual Studio 之间的循环依赖
基础教程推荐
- 如何在不破坏 vtbl 的情况下做相当于 memset(this, ...) 的操作? 2022-01-01
- 管理共享内存应该分配多少内存?(助推) 2022-12-07
- 为什么语句不能出现在命名空间范围内? 2021-01-01
- 使用从字符串中提取的参数调用函数 2022-01-01
- 如何“在 Finder 中显示"或“在资源管理器中显 2021-01-01
- Windows Media Foundation 录制音频 2021-01-01
- 在 C++ 中循环遍历所有 Lua 全局变量 2021-01-01
- 为 C/C++ 中的项目的 makefile 生成依赖项 2022-01-01
- 从 std::cin 读取密码 2021-01-01
- 如何使图像调整大小以在 Qt 中缩放? 2021-01-01