Help request on how to optimally link VC++.NET applications?

Hi!

I posted this question to a wrong forum earlier, now I am reposting it to the right forum.

My problem is that I write C++ aplications in tradional form, e.i., the programs include one header file (.h) and one implementation file (.cpp). Compiling is going very smoothly. However, I get problems with the linker and most of the time I get the notorious LNK 2020 error, "token could not be found etc".

The reason that I am getting this error message is that the linker cannot locate the implementation files and therefore cannot see where the "tokens" are implemented. It entails that you are supposed to load these .cpp files into the associated projects. My solution to this problem have been like this, because until now, I could not find a way to tell the linker that it should also look for .cpp files. It can become a tedious work if you have several projects, and some of your classes are naturally enough administrative classes, e.i., they contain several other classes you implemented in somewhere else.

The question remains : How can I tell the linker that it should also look for .cpp files Is there any linker option that I could not locate until now should be turned on or is there any macro description that can overcome this issue

If there is not what is the best way of linking VC++.Net applications (except dumping all the code to the header files)

I have very limited knowledge on Static Libraries. Can it be a solution I tried to create a static library but the compiler gave an error message saying that /CLR is not compatible with /MT. The combination of /CLR and /MD - as far as I can judge but I am not sure - provides a semi-static library. Is it usable The idea behind the static library is that you create an object pool by compiling your files and tell the linker that "what you are looking for is already compiled and you can find it in the object pool!" in stead of reloading and recompiling some of your files again and again.

Is there any recommendation/link/article/code snippet as to how to make a static library with .Net

Regards
Modeller



Answer this question

Help request on how to optimally link VC++.NET applications?

  • Cosmin Cojocar

    Hi,

    Sorry to hear that! Anyway, if you can not compile a project we recommend you the following book:

    http://www.dummies.com/WileyCDA/DummiesTitle/productCd-0764568523.html

    Good luck!



  • srividyaramesha

    I thank you very much all of you for your participation in the discussion. I believe I need to do some more explanation. Here is a very simple case :

    Assuming that we have only one solution and we have only one project in the solution.

    We implement the following classes :

    // ClassA
    // ClassB
    // ClassC

    // Header File(ClassA.h)
    #pragma once

    #ifndef __ClassA_H
    #define __ClassA_H

    namespace LinkerDemo{

    ref class ClassA{

    public :

    ClassA();

    void DoSomething();

    protected :

    // Some members

    private :

    // Some more members

    };
    }

    #endif

    // End of header file ClassA.h

    // Implementation File (ClassA.cpp)

    #include "ClassA.h"

    using namespace LinkerDemo;

    ClassA::ClassA()
    {

    // Implement Contructor

    }

    void ClassA::DoSomething()
    {

    // Implement the method : DoSomething

    }

    // End of implementation file ClassA.cpp


    // Header File(ClassB.h)
    #pragma once

    #ifndef __ClassB_H
    #define __ClassB_H

    #ifndef __ClassA_H
    #include "ClassA.h"
    #endif

    namespace LinkerDemo{

    ref class ClassB{

    public :

    ClassB();

    void DoSomethingElse();

    protected :

    // Here we will use ClassA as a protected member
    ClassA^ classA;

    private :

    // Some more members

    };
    }

    #endif

    // End of header file ClassB.h

    // Implementation File (ClassB.cpp)

    #include "ClassB.h"

    using namespace LinkerDemo;

    ClassB::ClassB()
    {

    // Implement Contructor

    }

    void ClassB::DoSomethingElse()
    {

    // Implement the method : DoSomethingElse

    }

    // End of implementation file ClassB.cpp

    To our VC++.Net project we load ClassB's header and implementation files and we press Build.

    - Compiling is OK
    - Linking gives error

    LNK2020 token ClassA::ctor
    LNK2020 token Class::DoSomething

    What we do is we just load ONLY the implemenation file of ClassA(ClassA.cpp) to our project, and we press Build

    - Linking is OK.

    if ClassA's contructor and the method DoSomething() were implemented in ClassA's header file we would not get any error message from the linker.

    Everything is OK, so far!

    Now let's put some flavor into our project by declaring another class, ClassC :

    // Header File(ClassC.h)
    #pragma once

    #ifndef __ClassC_H
    #define __ClassC_H

    #ifndef __ClassA_H
    #include "ClassA.h"
    #endif

    namespace LinkerDemo{

    ref class ClassC{

    public :

    ClassC();

    void DoNothing();

    protected :

    // Here is our flavor, namely we use ClassA again
    // Here the ClassA is a protected member
    ClassA^ classA;

    private :

    // Some more members

    };
    }

    #endif

    // End of header file ClassC.h

    // Implementation File (ClassC.cpp)

    #include "ClassC.h"

    using namespace LinkerDemo;

    ClassC::ClassC()
    {

    // Implement Contructor

    }

    void ClassC::DoNothing()
    {

    // Implement the method : DoNothing

    }

    // End of implementation file ClassC.cpp

    In our project, we have ClassB.h, ClassB.cpp, ClassC.h and ClassC.cpp files.

    When we press Build, we will get the same error message as we did before from the linker.

    If you think that loading ClassA.cpp will resolve the linker problem then you are dead wrong. What you will get is a new error message :

    (I cannot remember the exact linker error message and its code number, but the error message will more or less sound as follows) :

    Token CassA.ctor() has already been defined in ClassB
    Token ClassA.DoSomething() has already been defined in ClassB.

    Then the question is : Why don't you use it if it has already been defined!

    Please bear in mind that this is a simple illustration. In the real world, you have a number of different classes declared in a number of different projects, you can imagine the frustration.

    What is the solution

    Regards
    Modeller


  • WineNCheese

    It sould be the duty of the forum moderator to decide what is answer and what is spam. If spamming threads with nonse explanation is accepatble, then I am definitely on the wrong place. Just one word of advice : Please do not reply to a post in order to get a cheap credit when you do not understand the content of it. Your replies are telling your level of knowledge and competense.

    Take care guys!


  • Will Merydith

    Hi,

    You should not have the problem if is a normal VC++ project, all the CPP files are included on the compilation unless you specify so.

    Check the following things:

    1) Have your CPP files the following properties (when you click the file, the properties appear below on the IDE):
    -Contet = false
    -File Type = C/C++ Code
    Include in Project= True

    2) The 2020 error usually gives you the name of the function, are those functions on your CPP files or are in another DLL/LIBs If you use an external library you should check (References if is a .NET component) or right click on your project >> Properties >> Linker >> General >> Additional Library Directories.

    3)If the previous points does not fix your problem I recommend you to create a new project and add the files to the header and the source files folder again, as there is something wrong with your project.

    About static libraries is not the answer to your problem, it is just a different type of library. Here are some differences:

    Win32 Types:

    -Static Libraries:
    *) The libraries expose functions that can be executed without creating an instance of your object
    *) The OS expose many WIN32 functionality by this method, an you can call them using .NET using PInvoke
    *) You can create a static library if you need to create a win32 component to be consumed by lenguages like C# or VB
    *) In your design you must consider that is one call only, therefore they should be stateless
    *) The functions are published using Header files (not usable in c#/vb) or as definition files (used by PInvoke)

    -Dynamic Libraries
    *) When you need to publish function that is not stateless, and the consumer will need to create an instance of the component allowing several different context to have its own copy
    *) You can not consume them using C#/VB as these components usually expose the functionality using Header files, however you can consume them using a .NET C++ component
    *) You need to Load the library and dispose it when you consume it.

    .NET Types:
    *) Only exposes Dynamic Libraries (as a Class library)
    *) You can publish static and instanceable methods, the interface is a .NET one, therefore the integration is like any other .NET component

    Mixed environments:
    Sometimes is useful to mix the environments, for example, if you want to expose your win32 library to the .NET you can create a .NET class library that consumes a win32 static library and/or a win32 dynamic library (This is the way to consume win32 dll as I explained you before). The only limitation is that your managed classes can not contain unmanaged types, the workaround is exposing the win32 functionality through static classes.

    Hope this helps to understand.

    Let me know if you make any progress with the compiler, post again the results so I can help you.

    Cheers



  • Mortsdeh

    I think we're all just trying to be helpful. If the answer doesn't help you, then maybe there's a problem with the question. Let us know why the answer didn't help so we can provide better answers...


  • RayClark096

    I hope you found the right forum, C++ General would probably get you more answers. Strange problem. Why don't you just add a .cpp file to the project Right-click the project, Add, New Item, select the "Code" node, click C++ File (*.cpp). The linker will automatically link the .obj file for that source code file...


  • errolian

    I read your code until I saw this statement:
    "To our VC++.Net project we load ClassB's header and implementation files and we press Build."

    In order to create a ClassB instance, the program needs to be able to execute the ClassA constructor code. Since you didn't include ClassA.cpp, the linker cannot find that code and complains with LNK2020. It *can* find the code if you put the constructor code in the header. The solution is simple: put ClassA.cpp in the project.

    Another way to do this, and this might be why you're confused, is to build an assembly for ClassA. You can now build ClassB just by setting a reference to the ClassA assembly without having to put any of the ClassA implementation files in the project. The linker can find the constructor code for ClassA from the assembly metadata.


  • LSATL

    To the attention of the two last participants :

    I cannot see any new suggestion in your posts. What you posted here as answers have already been described above in order to tell how the linker works. Please read my post more carefully before posting your replies. This is not an issue of compiler, either. The purpose of the thread is to discuss the consept of "optimal linking of VC++.Net applications!".

    Regards

    Modeller


  • Eric Brinkerink

    Hi,

    I have followed your steps and the project compiles (one small change, I have included stdafx.h on every CPP file), indeed I can call the method DoSomething() from classA from class b. Here is my code, maybe you can spot something:

    // ClassA Header ***************************************
    #pragma once
    #ifndef __ClassA_H
    #define __ClassA_H

    namespace TestProblem {
    public ref class ClassA {
    public:
    ClassA();
    void DoSomething();
    };
    }
    #endif

    // ClassA CPP ***************************************
    #include "stdafx.h"
    #include "ClassA.h"

    using namespace TestProblem;

    ClassA::ClassA() { // Constructor }
    void ClassA::DoSomething() { // My Method }

    // Class B Header ***************************************
    #pragma once
    #ifndef __ClassB_H
    #define __ClassB_H

    #ifndef __ClassA_H
    #include "ClassA.h"
    #endif

    using namespace TestProblem;

    namespace TestProblem {
    public ref class ClassB {
    protected:
    ClassA^ classA;
    public:
    ClassB();
    void DoSomething();

    };
    }
    #endif

    // ClassB CPP **************************************
    #include "StdAfx.h"
    #include "ClassB.h"

    ClassB::ClassB() { }
    void ClassB::DoSomething() { classA->DoSomething(); }

    This code compiles without problem, can you check it please

    Regards



  • Gravy

    I agree with nobugz, I think that you weren't clear enough, and remember that you are in the wrong forum so we are trying to do our best. Otherwise post it in the C++ forum.

  • Help request on how to optimally link VC++.NET applications?