CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
+ Reply to Thread
Results 1 to 11 of 11
  1. #1
    Join Date
    Sep 2005
    Posts
    5

    Mixing managed and standard classes in a static library

    Hello,

    I need help to solve a link error. To minimice the source of problems, I made a prototype solution that generates the same error.

    The prototype solution have two projects:
    1) The first called "Libray", which I create using the Empty Project (.NET) wizard, and then changed the configuration type (in project properties) form "Application (.exe)" to "Static Library (.lib)".
    2) And the second called "Console", which I create using the Console Application (.NET) wizard, and added the Library.lib created after making my "Library" project (in project properties/linker/input/additional dependencies).

    Note that I require that the "Library" project has both, managed and unmanaged classes. So I created two classes in the "Library" project: "Managed" and "Standard". Below is the code:


    "Console\Console.cpp":

    #include "..\Library\Managed.h"
    #include "..\Library\Standard.h"
    using namespace System;
    int main() {

    Managed* managedPtr = new Managed();
    Standard standard;
    return 0;
    }


    "Library\Managed.h":

    #pragma once
    #using <mscorlib.dll>
    __gc class Managed {

    public:
    Managed(void);
    ~Managed(void);
    };


    "Library\Managed.cpp":

    #include ".\Managed.h"
    Managed::Managed(void) {}
    Managed::~Managed(void) {}


    "Library\Standard.h":

    #pragma once
    class Standard {

    public:
    Standard(void);
    ~Standard(void);
    };


    "Library\Standard.cpp":

    #include ".\Standard.h"
    Standard::Standard(void) {}
    Standard::~Standard(void) {}


    When I build the solution I get:
    "Build output":
    Linking...
    LINK : error LNK2020: unresolved token (06000002) Managed::.ctor
    LINK : error LNK2020: unresolved token (06000003) Managed::Finalize
    LINK : fatal error LNK1120: 2 unresolved externals

    What are I missing? Please help me.

    Just in case, here are the compiler and linker options:

    "Cosole" compiler command line:
    /Od
    /AI "C:\Solutions\SolveProblem\Debug"
    /D "WIN32"
    /D "_DEBUG"
    /D "_MBCS"
    /FD /EHsc /MTd /GS
    /Fo"Debug/"
    /Fd"Debug/vc70.pdb"
    /W3 /nologo /c /Zi /clr /TP
    /FU "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\mscor lib.dll"
    /FU "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Syste m.dll"
    /FU "C:\WINDOWS\Microsoft.NET\Framework\v1.1.4322\Syste m.Data.dll"

    "Console" linker command line:
    /OUT:"C:\Solutions\SolveProblem\Debug\Console.exe"
    /INCREMENTAL /NOLOGO /DEBUG /ASSEMBLYDEBUG
    /PDB:"C:\Solutions\SolveProblem\Debug/Console.pdb"
    /FIXED:No
    c:\projects\SolveProblem\Library\Debug\Library.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

    "Library" compiler command line:
    /Od /AI "c:\projects\SolveProblem\Library\Debug"
    /D "WIN32"
    /D "_DEBUG"
    /FD /EHsc /MTd /GS
    /Fo"Debug/"
    /Fd"Debug/vc70.pdb"
    /W3 /nologo /c /Zi /clr /TP

    "Library" linker command line:
    /OUT:"c:\projects\SolveProblem\Library\Debug/Library.lib"
    /NOLOGO

    Thancks
    Last edited by InMune; September 2nd, 2005 at 05:43 PM. Reason: make easyer to read

  2. #2
    Join Date
    Jan 2002
    Location
    Scaro, UK
    Posts
    5,940

    Re: Mixing managed and standard classes in a static library

    Try disabling the managed code option on the C++ file which is native. Just right click on the file in solution explorer, go to properties and you should be able to change the option in there.

    However I am still a bit confused that you're experiencing problems : there shouldn't be anything wrong with your code as far as I can tell.

    You are using the IDE aren't you ? This takes care of all of this sort of thing for you.

    Darwen.
    www.pinvoker.com - PInvoker - the .NET PInvoke Interface Exporter for C++ Dlls.

  3. #3
    Join Date
    Sep 2005
    Posts
    6

    Re: Mixing managed and standard classes in a static library

    Hi InMune,

    I have a similar problem with my code. In my case I have a native library and a managed WinForms application and when linking the library I get linker errors:

    Code:
    MainForm.obj : error LNK2028: unresolved token (0A000021) "public: bool __clrcall THERMO_LIB::Thermo::read_database(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)" (?read_database@Thermo ...
    
    MainForm.obj : error LNK2019: unresolved external symbol "public: bool __clrcall THERMO_LIB::Thermo::read_database(class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > const &,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > &)"
    When I create a Win32 console application and link the library, everything works fine. In both cases (console and WinForms application) I only added the library path to the linker options and the lib-file as additional dependency to the linker inputs.

    Now why does it work with the native console-application but not with the managed WinForms application? It seems there is a name mangling problem when using WinForms and native library. Does anyone know how to resolve this?

  4. #4
    Join Date
    Sep 2005
    Posts
    5

    Re: Mixing managed and standard classes in a static library

    Now I'm confused. I started from the very begining again.

    1) I created a new blank solution;
    2) added a new "Console (.NET)" project called "Console", and a new "Class Library (.NET)" project called "Library";
    3) changed the configuration type of the "Library" project form "dynamic library" to "static library";
    3) edited "console.cpp" to use the "Class1" class:

    #include "stdafx.h"
    #include "..\Library\Library.h"
    #using <mscorlib.dll>
    using namespace System;

    int _tmain()
    {
    Library::Class1* class1 = new Library::Class1;
    return 0;
    }

    4) built the solution and it worked.
    5) Then I explicity defined the constructor of Class1 (with the implementation in the .cpp file);
    6) I built the solution and I got

    LINK : error LNK2020: unresolved token (06000002) Library.Class1::.ctor

    Adding "Library.lib" (the file generated when building the "Library" project) to "aditional dependencies" in the "Console" project properties doesn't change the results.
    Doubtlessly, I'm missing something. This should be simple. Here I am not mixing managed and standard classes. There is only a single managed class (Class1). Please help me.
    Last edited by InMune; September 6th, 2005 at 04:12 PM.

  5. #5
    Join Date
    Dec 2004
    Posts
    85

    Re: Mixing managed and standard classes in a static library

    Try the following...

    Go to Project > Properties > Configuration Properties > Linker > Command Line and put your library name (including extension) under "Additional Options"

    (This is with Visual Studio 2005 Beta 2)
    Last edited by Ben_Phillips; September 6th, 2005 at 05:02 PM. Reason: some minor fixes

  6. #6
    Join Date
    Sep 2005
    Posts
    5

    Re: Mixing managed and standard classes in a static library

    Ben_Phillips,

    Thank you for your reply. I did whay you suggested and unfortunately nothing changed.
    I also use /VERBOSE in the linker options to see if the "Library.lib" is one of the files searched for definitions, and affirmatively it is.

  7. #7
    Join Date
    Sep 2005
    Posts
    6

    Re: Mixing managed and standard classes in a static library

    Hi again,

    I too started from scratch to find a solution and succeeded halfway with the following procedure:

    1. create new CLR console project
    2. change type from Application (*.exe) to static library (*.lib)
    3. copy my old C++ sources into the project and remove unneeded stuff
    4. compile lib (works fine without any other changes to the options)

    5. add new CLR console project to the solution
    6. include some header files and use classes + functions in the main()
    7. set project dependencies for new console project, so that first created lib becomes a dependency
    8. set include directory for library
    9. "Build solution..."

    And... it works!!! You don't even have to set any linker flags or library directories. Apparently the assemblies are found automatically, once they are in the same solution. So InMune, the solution for your problem seems to be found. Don't create the library with "CLR Class Library" but use a console application instead and change it to static library.


    HOWEVER, my problem isn't solved yet. I was quite surprise when I tried to create a simple WinForms application and copied the same code from my CLR console application into a button-event-handler. I set exactly the same options as in my console application but for some strange reason I get those linker errors again. Apparently there are differences in CLR console and WinForm projects, when it comes to linking to static libraries...

    Can anyone help me?

    Bye,
    Andreas

  8. #8
    Join Date
    Sep 2005
    Posts
    5

    Re: Mixing managed and standard classes in a static library

    ghorwin,

    Thank you for your reply. I started from scratch again following your instructions...

    1) Create a blank solution named “FindProblem”.

    2) Add a new project named “Library” applying the “Console (.NET)” template.

    3) Change the “Library” project’s configuration type to “Static Library (.lib)”.

    4) Remove the automatically generated “Library.cpp” file.

    5) Add a new generic C++ class named “Managed” to the “Library” project.

    6) Add a new project named “Console” applying the “Console (.NET)” template.

    7) Set the project dependencies so that “Console” depends on “Library”.

    8) Modify the automatically generated “Console.cpp” file of “Console” project such that it looks like this:

    #include "stdafx.h"
    #include "..\Library\Managed.h"
    #using <mscorlib.dll>
    using namespace System;

    int _tmain() {
    Console::WriteLine(S"Hello World");
    Managed* instance = new Managed;
    return 0;
    }
    9) Build the solution. It should work.

    10) Insert “__gc” before the “class” keyword in the “Managed” class definition (in Managed.h).

    11) Build the solution and the error message is there again:

    Linking...
    LINK : error LNK2020: unresolved token (06000002) Managed::.ctor
    LINK : error LNK2020: unresolved token (06000003) Managed::Finalize
    LINK : fatal error LNK1120: 2 unresolved externals

    The same that happends when I applied the "Class Library (.NET)" template to the "Library" project.

    Ghorwing, perhaps your scratch solution works because the code you moved to the static library project doesn't have managed classes. Am I right?
    Last edited by InMune; September 7th, 2005 at 11:31 AM.

  9. #9
    Join Date
    Sep 2005
    Posts
    6

    Re: Mixing managed and standard classes in a static library

    Hi InMune,

    right, my lib had only unmanaged classes. Sorry, thought I had found a solution to your problem.


    Just for the record, after a night of trying different things I managed to get my native c++ library linked together with a Windows Forms Application. Here's the catch:

    1. In the CLR - console project, with target Static Library, set the compiler option:
    Configuration properties -> General -> Common Language Runtime Support = Pure MSIL Common Language Runtime Support

    (must be the same as in the Windows Forms Application, otherwise you get a linker error)

    2. Set the library dependencies in your solution, so that your WinForms app has the library at dependency

    3. Set the following linker option in the WinForms app:
    Linker->General->Use Library Dependency Inputs = Yes

    With these settings, you don't even have to specify additional library directories or the library files.

    Ghorwin

  10. #10
    Join Date
    Sep 2005
    Posts
    6

    Re: Mixing managed and standard classes in a static library

    Heureka InMune,

    got it! The trick that worked with my WinForms class works also with libraries containing managed classes. I tried your example and could exactly reproduce your error message at first. Then I set the library dependency and the option "Use Library Dependency Inputs" in the linker section of the executable and it worked.

    Let's hope it works for you too.

    Bye,
    Ghorwin

  11. #11
    Join Date
    Sep 2005
    Posts
    5

    Re: Mixing managed and standard classes in a static library

    ghorwin,

    Im glad you solved your problem.
    Which version of Visual Studio .NET do you have? Mine, 2003, don't have the options you mentioned:

    Configuration properties -> General -> Common Language Runtime Support

    Configuration properties -> Linker->General->Use Library Dependency Inputs


    Appart from that, in your projet, does the static library with your native C++ code make use of ATL, MFC or CRT libraries? According to:
    ms-help://MS.VSCC.2003/MS.MSDNQTR.2003FEB.1033/vcmex/html/vcconConvertingManagedExtensionsForCProjectsFromPureIntermediateLanguageToMixedMode.htm
    ... you should not.

    Anyway, I intend to mix managed and standard classes with exastive use of the C++ STL in my static library. I think I can't conver such assembly to Pure MSIL. Am I right?
    Last edited by InMune; September 8th, 2005 at 02:42 PM.

+ Reply to Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts



HTML5 Development Center

Click Here to Expand Forum to Full Width