|
-
September 2nd, 2005, 05:24 PM
#1
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
-
September 6th, 2005, 01:06 AM
#2
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.
-
September 6th, 2005, 01:09 PM
#3
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?
-
September 6th, 2005, 04:07 PM
#4
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.
-
September 6th, 2005, 05:01 PM
#5
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
-
September 6th, 2005, 06:54 PM
#6
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.
-
September 7th, 2005, 12:05 AM
#7
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
-
September 7th, 2005, 11:18 AM
#8
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.
-
September 7th, 2005, 10:42 PM
#9
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
-
September 7th, 2005, 10:58 PM
#10
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
-
September 8th, 2005, 02:38 PM
#11
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.
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|