circular dependencies between dlls with visual stu

2019-01-22 23:03发布

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);
}

-> should compile into foo.dll

bar(int i)
{
   if (i > 0)
      foo(i - i);
}

-> should compile into bar.dll

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.

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.

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.

8条回答
老娘就宠你
2楼-- · 2019-01-22 23:24

The only way you'll get around this "cleanly" (and I use the term loosely) will be to eliminate one of the static/link-time dependencies and change it to a run-time dependency.

Maybe something like this:

// foo.h
#if defined(COMPILING_BAR_DLL)
inline void foo(int x) 
{
  HMODULE hm = LoadLibrary(_T("foo.dll");
  typedef void (*PFOO)(int);
  PFOO pfoo = (PFOO)GetProcAddress(hm, "foo");
  pfoo(x); // call the function!
  FreeLibrary(hm);
}
#else
extern "C" {
__declspec(dllexport) void foo(int);
}
#endif

Foo.dll will export the function. Bar.dll no longer tries to import the function; instead, it resolves the function address at runtime.

Roll your own error handling and performance improvements.

查看更多
别忘想泡老子
3楼-- · 2019-01-22 23:29

It's possible to use the LIB utility with .EXP files to "bootstrap" (build without prior .LIB files) a set of DLLs with a circular reference such as this one. See MSDN article for details.

I agree with other people above that this kind of situation should be avoided by revising the design.

查看更多
登录 后发表回答