Hi,
To test out "C++ Interop", I created a static library in VC++ 6.0:
Here is the contents of the header file (staticLibrary.h):
#ifndef STATICLIBTEST_H
#define STATICLIBTEST_H
#include <string>
using std::string;
int add352(int value);
string sayHello(string name);
#endif
Here is the implementation (staticLibrary.cpp):
#include "staticLibrary.h"
int add352(int value)
{
return value + 352;
}
string sayHello(string name)
{
string s1("Hello, you are the greatest, ");
return (s1 + name + "!\n");
}
This code compiles fine in VC++ 6.0 and it produces an object called "staticLibrary.lib"
I then started up another VC++ 6.0 project that links to the library,
calls one of its function (sayHello) and it works as expected.
Now, I start up Visual C++ Express to test out the exciting C++ Interop
capability that allows you to link to legacy libraries. In the
project settings, I included the path to the header file (under
Additional Include Directories) and the path to the library
(under Additional Library Directories).
In my C++/CLI code, I added the statement:
#include "staticLibrary.h"
Then I have the following code:
private: System::Void button1_Click(System::Object^ sender, System::EventArgs^ e) {
txtFunctionOut->Text = add352(System::Int32::Parse(txtFunctionIn->Text)).ToString();
}
When building this project, I get the following error message from the linker:
1>StaticLib.lib(staticLibrary.obj)
: error LNK2019: unresolved external symbol "void __cdecl
std::_Xlen(void)" ( _Xlen@std@@YAXXZ) referenced in function "private:
bool __thiscall std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char>
>::_Grow(unsigned int,bool)"
( _Grow@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@AAE_NI_N@Z)
1>StaticLib.lib(staticLibrary.obj)
: error LNK2019: unresolved external symbol "void __cdecl
std::_Xran(void)" ( _Xran@std@@YAXXZ) referenced in function "public:
class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >
& __thiscall std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char>
>::assign(class std::basic_string<char,struct
std::char_traits<char>,class std::allocator<char> >
const &,unsigned int,unsigned int)"
( assign@ $basic_string@DU $char_traits@D@std@@V $allocator@D@2@@std@@QAEAAV12@ABV12@II@Z)
Now, if I comment out the function "sayHello()" then it compiles
without errors and runs. So, it seems I am having problems using
the standard C++ "string" class. I have tried playing around with
the project settings but nothing has helped. Does anyone
have any idea what is causing this linker error
Thanks for any help or information!

When "It just works!" doesn't. :(
randomblink
I ask because I just rebuilt the static library without the /CLR switch and then rebuilt the application with the /CLR switch.
This time, I got a clean build but when I executed it I got the following error:
'DotNetApp.exe': Loaded 'C:\Documents and Settings\mong1\My Documents\Visual Studio 2005\Projects\DotNetApp\debug\DotNetApp.exe', Symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\ntdll.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\mscoree.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\kernel32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\advapi32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\rpcrt4.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd\msvcr80.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\msvcrt.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd\msvcm80.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\ole32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\gdi32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\user32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcp80d.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.DebugCRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_f75eb16c\msvcr80d.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\AMInit.dll', Binary was not built with debug information.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\wmfhotfix.dll', Binary was not built with debug information.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\shlwapi.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\Program Files\Webroot\Enterprise\Spy Sweeper\sis.dll', Binary was not built with debug information.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\comdlg32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\comctl32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\shell32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\oleaut32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\version.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\wsock32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\ws2_32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\ws2help.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.Windows.Common-Controls_6595b64144ccf1df_6.0.2600.2180_x-ww_a84f1ff9\comctl32.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorwks.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Culture.dll', No symbols loaded.
'DotNetApp.exe': Unloaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\Culture.dll'
'DotNetApp.exe': Loaded 'C:\WINDOWS\assembly\NativeImages_v2.0.50727_32\mscorlib\3bff3416cc5b17429de988a052f89be2\mscorlib.ni.dll', No symbols loaded.
'DotNetApp.exe' (Managed): Loaded 'C:\WINDOWS\assembly\GAC_32\mscorlib\2.0.0.0__b77a5c561934e089\mscorlib.dll', No symbols loaded.
'DotNetApp.exe' (Managed): Loaded 'c:\documents and settings\mong1\my documents\visual studio 2005\projects\dotnetapp\debug\DotNetApp.exe', Symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\mscorjit.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\diasymreader.dll', No symbols loaded.
'DotNetApp.exe': Loaded 'C:\WINDOWS\system32\rsaenh.dll', No symbols loaded.
'DotNetApp.exe' (Managed): Loaded 'C:\WINDOWS\WinSxS\x86_Microsoft.VC80.CRT_1fc8b3b9a1e18e3b_8.0.50727.42_x-ww_0de06acd\msvcm80.dll', No symbols loaded.
First-chance exception at 0x104817fd in DotNetApp.exe: 0xC0000005: Access violation writing location 0x0000000f.
A buffer overrun has occurred in DotNetApp.exe which has corrupted the program's internal state. Press Break to debug the program or Continue to terminate the program.
For more details please see Help topic 'How to debug Buffer Overrun Issues'.
shakalama
I'm confused. It did work with VS C++ 6.0.
I created another project in VS C++ 6.0 that is a console application and I linked it to the static library and I was able to call "sayHello()" and it worked.
If I comment out the sayHello() function and just leave add352() in the static library then it also works with an application written in VS C++ 2005.
I thought C++ interop (IJW) is supposed to allow you to link to a legacy native library as if you are working in standard C++.
I'm confused by what you mean by "depending on the CRT from 6.0 and 8.0. If I recompile the static library with VS C++ 2005, does that make the static library now depend on CRT 8.0 and it will then work
thedo
Nubby
Dietz
I set the compiler option for the runtime library to "Multi-thread DLL" and to produce a static library.
So, now the static native library is dependent on the same CRT as my main application.
Then I created a new project in C++/CLI with the /CLI option that links to the static native library.
I am still having problems getting it to compile. If I comment out the sayHello() function from the static native library then it seems to work. If I have the sayHello() function in there, I get unresolved externals when trying to link to it.
My question is: Is there some kind of limitation on using types such as the std:Strings class as a parameter to external library functions
If I bring all the source code (library, main application etc) into one project, then it compiles and seems to work.
Justin Pyfrom
janetfan95758
If I switch the project settings to use "Multiithreaded DLL Debug", on all my modules (instead of just Multithreaded DLL) then it seems to work!
So, I have a static native library that is compiled without the /CLR option that represents native legacy code.
Then I have a legacy native application that uses this library. I just compile the application (without the /CLR option) in VS 2005 and link with the library and it seems to work!
Then I also have a new C++/CLI application that also uses this static library. All I do is compile (with the /CLR option) and link it with the static library and it seems to work!
This is what I was hoping for when I read about "It Just Works".
I was hoping that all we needed to do was to recompile our legacy code with the new VS 2005 compiler and keep it as native code (static LIB etc).
Then we would write a managed C++/CLR wrapper that links to the static native library and act as a proxy to any other .NET language. This will allow our future .NET based code to use our legacy libraries.
At the same time, our legacy applications will continue to work with our legacy libraries.
So, if this continues to work, then I will be very happy.
BTW, one odd thing I noticed is that after the return from sayHello(), the string that was returned seemed to have a square appended at the end (is it the NULL terminator ).
2162
I followed the steps of repro, but unfortunately I get a clean build. The code does look like a legacy code, but it should still compile. You may try using ildasm to figure out what exactly is wrong with metadata. You may find some more information in http://msdn2.microsoft.com/en-US/library/zkf0dz41.aspx.
Also you may not need to recompile your legacy code with /clr. Pick parts of your application that are going to use managed code and only recompile those parts. Throwing /clr on all application is a bad idea in many cases. Keep /clr only to parts when you see clear benefit of using managed code and there is simple alternative solution that can be implemented using native code.
Nikola
zeljko62
I am not sure what the issue is exactly because I do not see what errors are issue by the compiler or linker. However using std::string as a return parameter from a static library should not be an issue. It is not a good practice, but it should work fine.
Nikola
arashikage
Okay, I re-read that article on "It Just Works" on www.codeguru.com site and I misread it. It only works if the library is a DLL as you said. For some reason I thought it would work as a static library.
But just to clear things up, am I correct to think that static linking should work if I recompile the code with VS C++ 2005 Thanks.
xboxracer
Jonathan is absolutely right. You are creating static library that depends on CRT from 6.0 and attempting to link it with the code that depends on CRT 8.0. This is not going to work. It has nothing to do with IJW, it does not work in native code also. If you would like to build a module that can be used with different versions of CRT, it has to be build as a DLL with exports that obey rules of data passing across DLL boundary.
Nikola
Nick Hart
I have tried many permutations in trying to get this work. I even have tried just working in pure native mode (in other words, using VS 2005 as if it were VS 6.0) and I still get linker errors.
If I combine all the source code (library and application) into one project, it seems to work. So, it almost seems like I can't pass std::strings as parameters if the static library is an external file.
Oh, I guess I should mention that I've been doing my testing with Visual Studio C++ 2005 Express (instead of VS 2005) but I didn't think that should make any difference
JohnWP
This is supposed to represent old legacy C/C++ code that I want to migrate to C++/CLI.
So, I take this old code and recompile with VS C++ 2005. The old code looks like this:
Here is the header file
#ifndef STATICLIBTEST_H
#define STATICLIBTEST_H
#include <string>
using std::string;
int add352(int value);
string sayHello(string name);
#endif
Here is the source file:
#include "staticLibrary.h"
int add352(int value)
{
return value + 352;
}
string sayHello(string name)
{
string s1("Hello, you are the greatest, ");
return (s1 + name + "!\n");
}
This has been compiled with VS 2005 with the /CLR switch, Multithread DLL and produces a LIB file called "StaticLibDotNet.lib"
I now create the following C++/CLR console application that will link to this static library:
// DotNetApp.cpp : main project file.
#include "stdafx.h"
#include "staticLibrary.h"
using namespace System;
int main(array<System::String ^> ^args)
{
int a = add352(27);
string s;
string name = "John";
s = sayHello(name);
return 0;
}
In the project settings, I have the additional include and library directories pointing to the correct locations. In the additional dependencies, I have added "StaticLibDotNet.lib". I have it set to compile with the /CLR switch and Multithreaded DLL. When I try to compile, I get the following errors:
1>------ Rebuild All started: Project: DotNetApp, Configuration: Debug Win32 ------
1>Deleting intermediate and output files for project 'DotNetApp', configuration 'Debug|Win32'
1>Compiling...
1>stdafx.cpp
1>Compiling...
1>DotNetApp.cpp
1>AssemblyInfo.cpp
1>Generating Code...
1>Compiling resources...
1>Linking...
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.ostreambuf_iterator<char,std::char_traits<char> >): (0x0200000f).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.ostreambuf_iterator<wchar_t,std::char_traits<wchar_t> >): (0x02000010).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.logic_error): (0x02000019).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.basic_string<char,std::char_traits<char>,std::allocator<char> >): (0x0200001a).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.domain_error): (0x0200001c).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.invalid_argument): (0x0200001d).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.length_error): (0x0200001e).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.out_of_range): (0x0200001f).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.runtime_error): (0x02000020).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.overflow_error): (0x02000021).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.underflow_error): (0x02000022).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.range_error): (0x02000023).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._Locinfo): (0x02000025).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (_Locimp): (0x0200002b).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (failure): (0x02000037).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.basic_string<wchar_t,std::char_traits<wchar_t>,std::allocator<wchar_t> >): (0x02000048).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<char,std::allocator<char> >): (0x02000058).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.istreambuf_iterator<char,std::char_traits<char> >): (0x02000059).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std.istreambuf_iterator<wchar_t,std::char_traits<wchar_t> >): (0x0200005a).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._String_val<wchar_t,std::allocator<wchar_t> >): (0x0200005e).
1>StaticLibDotNet.lib(staticLibrary.obj) : error LNK2022: metadata operation failed (8013118D) : Inconsistent layout information in duplicated types (std._Iterator_base): (0x0200007a).
1>LINK : fatal error LNK1255: link failed because of metadata errors
1>Build log was saved at "file://c:\Documents and Settings\mong1\My Documents\Visual Studio 2005\Projects\DotNetApp\DotNetApp\Debug\BuildLog.htm"
1>DotNetApp - 22 error(s), 0 warning(s)
========== Rebuild All: 0 succeeded, 1 failed, 0 skipped ==========
Any help would be greatly appreciated. I've been working on trying to understand this material (because I was tasked with researching the best approach on migrating our legacy code base to .NET) and it's been frustrating. The concepts seem pretty straight forward but I can't get my simple examples to work in order to verify my understanding.