I referred this somewhat similar question before asking this, but unable to solve my problem
I am looking at an old application with many solutions. The problem is happening in one of the solutions (say S). Here is the situation:
/clr
option with
that/clr
enabled and created one header file for
function declaration and a .cpp file for the function definition; The
C# call is made under it; P2 compiles fineand a warning:
warning LNK4098: defaultlib 'MSVCRT' conflicts with use of other libs; use /NODEFAULTLIB:library
Now with all these, I get 3 linker errors in P1:
error LNK2005: "private: __thiscall type_info::type_info(class type_info const &)" (??0type_info@@AAE@ABV0@@Z) already defined in libcmtd.lib(typinfo.obj)
error LNK2005: "private: class type_info & __thiscall type_info::operator=(class type_info const &)" (??4type_info@@AAEAAV0@ABV0@@Z) already defined in libcmtd.lib(typinfo.obj)
error LNK1169: one or more multiply defined symbols found
This error is available at many online forums including this website. But somehow I am not able to fix it after trying those options (I am new to .NET framework).
Important point is that, even if I remove the C# code from P2 then also the same error appears.
What is the correct way to fix it?
Update:
P2 just contains 1 header file with function declaration and 1 source file with function definition which is a 1 line call to the C# method; e.g.
void Class::foo () { // A static function inside Class
std::string x = marshal_as<std::string>(C#_function);
// ...
}
P2 is newly added to compile with /clr
(Removing P2 makes the solution compile fine).
I am compiling both P1 and P2 with /MD[d]
options. And the above error is thrown by P1.
If I make P2 from static library (.lib) to dynamic linked library (.dll), then the above errors goes away. And the new linker error comes for the foo
itself for undefined reference:
error LNK2019: unresolved external symbol "public: void __cdecl Class::foo()" referred in function { some function of P1 }
I was finally able to solve this problem with lots of trial and error and internet searches in and out of StackOverflow. At least the linker errors are gone, don't know what other things may pop up, but it's a good sign.
I will try to document as much as possible below:
How to link 2 dlls under the same project with one being /clr
and other non clr
?
/clr
project/clr
, if it contains all .cpp code and no .c codeSo far it's good, but the problem comes when the new project (P2) function definition is not linked with the original project (P1). It gives various linker errors.
The steps are with VC++2010 for novice users (like me).
Configuring P1:
Add -> New Project -> Other
languages -> VC++ -> CLR empty project
and name it (say P2) ;Add the header file and .cpp file in appropriate sections of the projectProperties -> Configuration Properties ->
C/C++ -> Code Generation -> Runtime Library to Multi threaded DLL:
/MD[d]
; Which is essentialProperties -> Configuration Properties -> C/C++ ->
General -> Additional Include Directories
; So that you can include
the new header file of P2 anywhere in the P1's source filesProperties -> Common Properties ->
Framework and Reference -> Add New Reference
and you should be able
to see the P2 there; Just add itConfiguring P2:
Properties -> Common Properties ->
Framework and References -> Add New Reference -> <Select the C# or
whatever external DLL you would want to call from P2>
DLL
under Properties
-> Configuration Properties -> General -> Project Defaults -> Configuration Type -> Dynamic Library (DLL)
Output Directory
and Intermediate Directory
also in sync (not exactly same) with that of P1Properties -> Configuration Properties ->
Linker -> General -> Ignore Import Library -> No
; I did this because
it's like that in P1 as well__declspec(dllexport)
(or __declspec(dllimport)
, not sure but
both works); I got this crucial info from this question and this question
And with above steps the build was successful!
Probably there could be things which are missed, and due to that I face some runtime issues. However at least I was able to link 2 DLL projects under the same solution which are with and without /clr
.
Well, you are not linking C# code, that's just not possible so that's not the source of the problem. The warning is the first hint at the core problem, you are trying to link code that was compiled with /MT and thus has a dependency on libcmtd.lib, the static version of the CRT. Your C++/CLI code will always be compiled with /MD and thus has a dependency on msvcrtd.lib, the version of the CRT that's stored in a DLL and can be shared between multiple modules.
You cannot mix both versions of the CRT in one executable, that's why the linker objects with LNK4098. The link fails when it sees two copies of the type_info class implementation, one from libcmtd.lib and another from msvcrtd.lib and cannot decide which one you really want.
Furthermore, a C++/CLI project has a rock hard requirement that you must use /MD and link with msvcrtd.lib, the static version of the CRT is not supported. You must go back to the project that compiles the code with /MT and change the setting to /MD. Project + Properties, C/C++, Code Generation, Runtime library setting. It isn't otherwise clear which particular project has this problem. Beware of .lib files you got from elsewhere that were just compiled with the wrong setting. If you have no idea which is the troublemaker then grep the files for "-MTd", the .lib files contain a copy of the original compile command.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With