Circular Dependencies Between Libraries

Discussion in 'C++' started by barias@axiscode.com, Oct 19, 2006.

  1. Guest

    Although circular dependencies are something developers should normally
    avoid, unfortunately they are very easy to create accidentally between
    classes in a VS project (i.e. circular compile-time dependencies). But
    then I started wondering how "easy" it would be to similarly make a
    NON-RUNTIME circular dependency between (implicitly linked) DLLs.
    Indeed authors like John Lakos, who focus on compile/link-time
    dependencies (not run-time), tell us to avoid such circular
    dependencies between "packages" (i.e. libraries). But to my surprise,
    evidently it isn't possible to create a circular library dependency
    even if you try...

    Tonight I tried to make a circular dependency by creating two Win32
    console DLLs in a new VC++ solution, and attempted to make both have a
    (implicit link) dependency on the other. But no matter how I tried, in
    the end I always got a linker error about missing symbols - because DLL
    'A' needed the type library of DLL 'B', which did not exist yet because
    DLL 'B' needed the type library of DLL 'A'. A similar problem occurred
    if I made both projects just static libraries (instead of DLLs).

    In the end, I concluded that to make the circular dependency I would
    need to involve some kind of externalized interface descriptions - such
    as IDL (e.g. CORBA?). But if I used IDL in that fashion, I figure I
    would end up with something that is more akin to circular runtime
    dependency rather than a non-runtime dependency (and even then, it may
    no longer qualify as truly circular).

    Can anyone give me an example of how DLLs (or even static LIBs) can get
    involved in a circular dependency? I'm scrutinizing this topic because
    authors like Robert Martin or John Lakos ("Large Scale C++") talk about
    how "packages" (aka libraries) should be forced away from cyclical
    dependencies. Well, why make all that effort of preaching against
    circular package/library dependencies, if its not even possible to make
    such circular dependencies in the first place?
     
    , Oct 19, 2006
    #1
    1. Advertising

  2. Gavin Deane Guest

    wrote:
    > Although circular dependencies are something developers should normally
    > avoid, unfortunately they are very easy to create accidentally between
    > classes in a VS project (i.e. circular compile-time dependencies). But
    > then I started wondering how "easy" it would be to similarly make a
    > NON-RUNTIME circular dependency between (implicitly linked) DLLs.
    > Indeed authors like John Lakos, who focus on compile/link-time
    > dependencies (not run-time), tell us to avoid such circular
    > dependencies between "packages" (i.e. libraries). But to my surprise,
    > evidently it isn't possible to create a circular library dependency
    > even if you try...
    >
    > Tonight I tried to make a circular dependency by creating two Win32
    > console DLLs in a new VC++ solution, and attempted to make both have a
    > (implicit link) dependency on the other. But no matter how I tried, in
    > the end I always got a linker error about missing symbols - because DLL
    > 'A' needed the type library of DLL 'B', which did not exist yet because
    > DLL 'B' needed the type library of DLL 'A'. A similar problem occurred
    > if I made both projects just static libraries (instead of DLLs).
    >
    > In the end, I concluded that to make the circular dependency I would
    > need to involve some kind of externalized interface descriptions - such
    > as IDL (e.g. CORBA?). But if I used IDL in that fashion, I figure I
    > would end up with something that is more akin to circular runtime
    > dependency rather than a non-runtime dependency (and even then, it may
    > no longer qualify as truly circular).
    >
    > Can anyone give me an example of how DLLs (or even static LIBs) can get
    > involved in a circular dependency? I'm scrutinizing this topic because
    > authors like Robert Martin or John Lakos ("Large Scale C++") talk about
    > how "packages" (aka libraries) should be forced away from cyclical
    > dependencies. Well, why make all that effort of preaching against
    > circular package/library dependencies, if its not even possible to make
    > such circular dependencies in the first place?


    VC++, Windows programming, IDL, DLLs are all off-topic here. However,
    if you can formulate your question as a pure C++ question
    http://www.parashift.com/c -faq-lite/how-to-post.html#faq-5.9
    http://www.parashift.com/c -faq-lite/how-to-post.html#faq-5.8
    then you should get some help. Alternatively, if your question is
    specific to Windows, try asking in one of the Windows programming
    groups suggested in FAQ 5.9.

    Gavin Deane
     
    Gavin Deane, Oct 19, 2006
    #2
    1. Advertising

  3. * :
    >
    > Can anyone give me an example of how DLLs (or even static LIBs) can get
    > involved in a circular dependency? I'm scrutinizing this topic because
    > authors like Robert Martin or John Lakos ("Large Scale C++") talk about
    > how "packages" (aka libraries) should be forced away from cyclical
    > dependencies. Well, why make all that effort of preaching against
    > circular package/library dependencies, if its not even possible to make
    > such circular dependencies in the first place?


    Circular dependencies are possible (in practice) for all kinds of
    modules created in C++.

    Start by creating two functions foo and bar that depend on each other:

    <file foo.cpp>
    void bar();
    void foo() { bar(); }
    </file foo.cpp>

    <file bar.cpp>
    void foo();
    void bar() { foo(); }
    </file bar.cpp>

    Now compile these files separately: you have circularly dependent object
    files.

    Create a static library from each: you have circularly dependent static
    libraries.

    Create a DLL from each: you have circularly dependent DLLs (of course,
    how to create such DLLs is off-topic in this group, which is about the
    C++ language, so for specific tool usage ask in appropriate group).

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 19, 2006
    #3
  4. Greg Guest

    wrote:
    > Can anyone give me an example of how DLLs (or even static LIBs) can get
    > involved in a circular dependency? I'm scrutinizing this topic because
    > authors like Robert Martin or John Lakos ("Large Scale C++") talk about
    > how "packages" (aka libraries) should be forced away from cyclical
    > dependencies. Well, why make all that effort of preaching against
    > circular package/library dependencies, if its not even possible to make
    > such circular dependencies in the first place?


    Since dynamic libraries are a subject of active interest and
    development in the C++ standard, I would say that dynamic libraries are
    not entirely off-topic. At any rate this question is easily answered:
    It is certainly possible to build mutually dependent libraries. The
    trick is simply to build one library against a stub library version of
    the other.

    Greg
     
    Greg, Oct 19, 2006
    #4
  5. Noah Roberts Guest

    wrote:
    > Although circular dependencies are something developers should normally
    > avoid, unfortunately they are very easy to create accidentally between
    > classes in a VS project (i.e. circular compile-time dependencies). But
    > then I started wondering how "easy" it would be to similarly make a
    > NON-RUNTIME circular dependency between (implicitly linked) DLLs.
    > Indeed authors like John Lakos, who focus on compile/link-time
    > dependencies (not run-time), tell us to avoid such circular
    > dependencies between "packages" (i.e. libraries). But to my surprise,
    > evidently it isn't possible to create a circular library dependency
    > even if you try...
    >
    > Tonight I tried to make a circular dependency by creating two Win32
    > console DLLs in a new VC++ solution, and attempted to make both have a
    > (implicit link) dependency on the other. But no matter how I tried, in
    > the end I always got a linker error about missing symbols - because DLL
    > 'A' needed the type library of DLL 'B', which did not exist yet because
    > DLL 'B' needed the type library of DLL 'A'. A similar problem occurred
    > if I made both projects just static libraries (instead of DLLs).
    >
    > In the end, I concluded that to make the circular dependency I would
    > need to involve some kind of externalized interface descriptions - such
    > as IDL (e.g. CORBA?). But if I used IDL in that fashion, I figure I
    > would end up with something that is more akin to circular runtime
    > dependency rather than a non-runtime dependency (and even then, it may
    > no longer qualify as truly circular).
    >
    > Can anyone give me an example of how DLLs (or even static LIBs) can get
    > involved in a circular dependency? I'm scrutinizing this topic because
    > authors like Robert Martin or John Lakos ("Large Scale C++") talk about
    > how "packages" (aka libraries) should be forced away from cyclical
    > dependencies. Well, why make all that effort of preaching against
    > circular package/library dependencies, if its not even possible to make
    > such circular dependencies in the first place?


    We had one where one lib required the header of the other and then
    there was a solid dependency the other way. I fixed that one.

    We also have some sort of funky cyclic dependency solved by compiling
    one into the exe and loading the other. I'll fix that one eventually.
     
    Noah Roberts, Oct 19, 2006
    #5
  6. Guest

    > Start by creating two functions foo and bar that depend on each other:
    >
    > Now compile these files separately: you have circularly dependent object
    > files.
    >
    > Create a static library from each: you have circularly dependent static
    > libraries.


    The simplistic version you describe here, isn't possible. As soon as
    you try to link either one of these seperate object files, you will get
    a linker error. As another poster pointed out, between two libs 'A'
    and 'B', you'd have to make some kind of "3rd party" stub library -
    such as 'BStub', and have 'A' link against that.

    But using that kind of approach hearkens back to using something like
    IDL (which, when compiled, produces lib stubs - at least it does in the
    case of CORBA). As such, it is actually "difficult" to produce a
    circular dependency, people don't "accidentally" use IDL in scenarios
    like this...
     
    , Oct 19, 2006
    #6
  7. <> wrote in message
    news:...
    :> Start by creating two functions foo and bar that depend on each
    other:
    : >
    : > Now compile these files separately: you have circularly dependent
    object
    : > files.
    : >
    : > Create a static library from each: you have circularly dependent
    static
    : > libraries.
    :
    : The simplistic version you describe here, isn't possible. As soon as
    : you try to link either one of these seperate object files, you will
    get
    : a linker error. As another poster pointed out, between two libs 'A'
    : and 'B', you'd have to make some kind of "3rd party" stub library -
    : such as 'BStub', and have 'A' link against that.
    :
    : But using that kind of approach hearkens back to using something like
    : IDL (which, when compiled, produces lib stubs - at least it does in
    the
    : case of CORBA). As such, it is actually "difficult" to produce a
    : circular dependency, people don't "accidentally" use IDL in scenarios
    : like this...

    What you are facing is just a limitation of the tool chain you are
    using (or of your understanding of it).
    There is no need for such a thing as IDL or Corba. In your case it
    might be enough to comment-out the contents of the function body
    of either library to make a first compile. Then uncomment the code,
    rebuild that library, and you're done.

    Again, as others pointed out, the specifics of how to do this on
    the platform you are using are out of topic here.


    --
    http://ivan.vecerina.com/contact/?subject=NG_POST <- email contact form
     
    Ivan Vecerina, Oct 19, 2006
    #7
  8. * :
    >> Start by creating two functions foo and bar that depend on each other:
    >>
    >> Now compile these files separately: you have circularly dependent object
    >> files.
    >>
    >> Create a static library from each: you have circularly dependent static
    >> libraries.

    >
    > The simplistic version you describe here, isn't possible.


    T:\> type con >foo.cpp
    void bar();
    void foo() { bar(); }
    ^Z

    T:\> type con >bar.cpp
    void foo();
    void bar() { foo(); }
    ^Z

    T:\> cl /GX /GR /c foo.cpp bar.cpp
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
    Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

    foo.cpp
    bar.cpp
    Generating Code...

    T:\> lib foo.obj /out:foo.lib
    Microsoft (R) Library Manager Version 7.10.3077
    Copyright (C) Microsoft Corporation. All rights reserved.


    T:\> lib bar.obj /out:bar.lib
    Microsoft (R) Library Manager Version 7.10.3077
    Copyright (C) Microsoft Corporation. All rights reserved.


    T:\> dir /b *.lib
    bar.lib
    foo.lib

    T:\> type con >main.cpp
    void foo();
    int main()
    {
    foo();
    }
    ^Z

    T:\> cl /GX /GR main.cpp foo.lib bar.lib
    Microsoft (R) 32-bit C/C++ Optimizing Compiler Version 13.10.3077 for 80x86
    Copyright (C) Microsoft Corporation 1984-2002. All rights reserved.

    main.cpp
    Microsoft (R) Incremental Linker Version 7.10.3077
    Copyright (C) Microsoft Corporation. All rights reserved.

    /out:main.exe
    main.obj
    foo.lib
    bar.lib

    T:\> dir /b *.exe
    main.exe

    T:\> _



    > As soon as
    > you try to link either one of these seperate object files, you will get
    > a linker error.


    Will I?


    > As another poster pointed out, between two libs 'A'
    > and 'B', you'd have to make some kind of "3rd party" stub library -
    > such as 'BStub', and have 'A' link against that.


    Do I really have to?


    > But using that kind of approach hearkens back to using something like
    > IDL (which, when compiled, produces lib stubs - at least it does in the
    > case of CORBA). As such, it is actually "difficult" to produce a
    > circular dependency, people don't "accidentally" use IDL in scenarios
    > like this...


    Sorry, that's techo-babble.

    --
    A: Because it messes up the order in which people normally read text.
    Q: Why is it such a bad thing?
    A: Top-posting.
    Q: What is the most annoying thing on usenet and in e-mail?
     
    Alf P. Steinbach, Oct 19, 2006
    #8
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Suzanne Vogel
    Replies:
    2
    Views:
    2,639
    Suzanne Vogel
    Jun 26, 2003
  2. crichmon
    Replies:
    3
    Views:
    784
    crichmon
    Jun 28, 2004
  3. Dylan
    Replies:
    7
    Views:
    595
    Dylan
    Jul 7, 2004
  4. ernesto basc?n pantoja

    Circular dependencies

    ernesto basc?n pantoja, Nov 29, 2004, in forum: C++
    Replies:
    2
    Views:
    3,805
    Larry Brasfield
    Nov 29, 2004
  5. Kiuhnm
    Replies:
    16
    Views:
    762
    Jonathan Mcdougall
    Jan 3, 2005
Loading...

Share This Page