I've a C++/CLI project and I would need to compute the median on arrays (as fast as possible). I've found here a solution, but when I try it in my C++/CLI project I get the following error:
error LNK2019: unresolved external symbol _CrtDbgReportW referenced in function "public: short & __cdecl std::vector<short,class std::allocator<short> >::operator[](unsigned __int64)"
Is this due to the fact that I'm compiling in /MD? If yes and since it seems that /clr and /MT cannot be combined, what I should use? Any suggestion?
The credit goes to Hans Passant, however I reply in case somebody else would experience the same. In my C++/ClI project under Properties>C/C++>Code Generation>Runtime Library, while being in DEBUG mode I had /MD instead than /MDd.
Related
I'm writing a CLR wrapper for an unmanaged C++ library.
There are two files I'm including from the unmanaged lib:
//MyCLIWrapper.h
#include "C:\PATH\TO\UNMANAGED\Header.h"
#include "C:\PATH\TO\UNMANAGED\Body.cpp"
Then I'm writing CLI implementations for the unmanaged library functions:
//MyCLIWrapper.h
// includes ...
void MyCLIWrapper::ManagedFunction()
{
UnmanagedFunction(); // this function is called successfuly
}
However, if my Unmanaged function contains calls to other functions that are defined in other unmanaged header files. This causes a compiler linkage error.
If I add includes to the unmanaged headers that define these functions, my errors get resolved. However, there is a lot of functions, and a lot of includes required.
Is there a different way to approach this?
EDIT:
P.S.
My managed code is in a separate Visual Studio project (output - DLL), and the compile settings are set to /CLR. Unmanaged code is in a separate Win32 project (output - DLL).
Also, after more research I concluded that theoretically I could set my Win32 unmanaged project to CLR and just add my managed classes and headers in there as an entry point, and then it would all compile into a single DLL file. That would probably solve (?) the linkage errors. However, I would prefer to preserve the loose coupling as well as the additional series of problems that can raise from setting my unmanaged project to CLR.
EDIT #2:
The unmanaged class that I'm referencing (body.cpp, header.h) contains includes to the required files that define the functions that are causing the problems. However, my managed code doesn't pick up on the includes that are in the unmanaged body.cpp and header.h.
Linker errors are a different kettle of fish from compiler errors. You forgot to document the exact linker errors you see, but a very common mishap when you compile code with /clr in effect is that the default calling convention for non-C++ member function changes. The default is __clrcall, a convention that's optimized for managed code. While functions compiled without /clr defaults to __cdecl. Which changes the way the function name is mangled. You see this back in the linker error message, is shows that it is looking for a __clrcall function and can't find it.
You'll need to either explicitly declare your functions in the .h file with __cdecl. Or tell the compiler that these functions are not managed code. Which is the best way to tackle it:
#pragma managed(push, off)
#include "unmanagedHeader.h"
#pragma managed(pop)
Solution was fairly simple:
I added both unmanaged and managed projects to a single solution in Visual Studio.
Set the unmanaged project's "Configuration Type" to "Static Library" (.lib).
Right click on the managed project -> References -> Add Reference -> Projects -> -> Add Reference.
Then in my managed class, I include the header.h (only) just like I did in my question.
Compiled successfully!
Thank you
I've been using OpenGL with glut for quite a while now and have never encountered this issue.
I've been trying to include the glut library in my c++/cli project for the use of it's library functions like glutMouseFunc etc. My project already uses gl.h and glu.h. However the moment I include:
#include <gl/glut.h>
I get the following string of error messages.
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(490): error C3641: 'glutInit_ATEXIT_HACK' : invalid calling convention '__stdcall ' for function compiled with /clr:pure or /clr:safe
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(490): error C2664: '__glutInitWithExit' : cannot convert parameter 3 from 'void (__cdecl *)(int)' to 'void (__cdecl *)(int)'
1> Address of a function yields __clrcall calling convention in /clr:pure and /clr:safe; consider using __clrcall in target type
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(507): error C3641: 'glutCreateWindow_ATEXIT_HACK' : invalid calling convention '__stdcall ' for function compiled with /clr:pure or /clr:safe
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(507): error C2664: '__glutCreateWindowWithExit' : cannot convert parameter 2 from 'void (__cdecl *)(int)' to 'void (__cdecl *)(int)'
1> Address of a function yields __clrcall calling convention in /clr:pure and /clr:safe; consider using __clrcall in target type
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(553): error C3641: 'glutCreateMenu_ATEXIT_HACK' : invalid calling convention '__stdcall ' for function compiled with /clr:pure or /clr:safe
1>C:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\gl/glut.h(553): error C2664: '__glutCreateMenuWithExit' : cannot convert parameter 2 from 'void (__cdecl *)(int)' to 'void (__cdecl *)(int)'
1> Address of a function yields __clrcall calling convention in /clr:pure and /clr:safe; consider using __clrcall in target type
I've read in a few other places that similar problems have been solved by switching the clr support in the project's properties (properties>configuration properties>general>common language runtime support) to anything that's not clr:safe or clr:pure.
I've in fact tried compiling with all 4 available versions of clr support:
Common Language runtime support (/clr)
Pure MSIL Common Language Runtime Support (/clr:pure)
Safe MSIL Common Language Runtime Support (/clr:safe)
Common Language Runtime Support, Old Syntax (/clr:oldSyntax)
However I still receive the same error message. I've no idea where this issue comes from. I've used glut in other projects (c++ only), and never encountered this problem until i started using c++/cli.
Any insight into what this could be would be greatly appreciated.
Thanks in advance,
Guy
(By the way, I'm using Visual Studio 2010 if it turns out to be of any relevance.)
The error message you're displaying will not occur if using /clr to compile a file, only /clr:pure or /clr:safe.
You definitely need to use /clr, and not use /clr:pure or /clr:safe, as the latter flags will not allow you to use native code at all within the .cpp file. Make sure you don't have a single file overriding the project settings for /clr, either, as this can cause the compiler to create errors such as you're displaying for those files.
You'll need to let the compiler know that glut.h is a header for unmanaged code. If it doesn't know then it will assume that is contains managed functions and it doesn't like what it sees. You do so like this:
#pragma managed(push, off)
#include <gl/glut.h>
#pragma managed(pop)
A more general way to keep out of trouble like this is by strictly separating the C++/CLI code from the native code. You can turn on the /clr option for individual source files, it doesn't need to be turned on for every source code file in your project. This also helps to get native code compiled to machine code instead of IL, it is faster that way.
I am trying to call functions in c++ from C# and to do this, I created a C++/CLI project to wrap C++ codes.
My code compiles, but during linkage, I am getting error that linker can not find methods which are defined in c++ code.
The c++ code is a static library and I add a reference to it in C++/CLI project (common properties -> framework and references -> add new reference)
My questions:
Is there anything else should I do?
is adding reference in this sections means that the reference is a .net assembly? Or could it be a reference to a static library.
Edit 1
I am sing VS 2012 on windows 7 64bit
Linker Error:
Error 3 error LNK2019: unresolved external symbol "public: static class MyFile __cdecl MyFile::ReadMyFile(char *)" (?ReadMyFile#MyFile##$$FSA?AV1#PAD#Z) referenced in function "public: static class MyFileWrapper::MyFileWrapper ^ __clrcall MyFileWrapper::MyFileWrapper::ReadMyFile(class System::String ^)" (?ReadMyFile#MyFileWrapper#1#$$FSMP$AAV11#P$AAVString#System###Z) MyFileWrapper.obj
You didn't post the linker error message, that makes it difficult to answer this question accurately. The most common causes:
Forgetting to tell the compiler that the function is a native function and not a managed one. You can tell from the linker error message when you see it using the __clrcall calling convention, native code normally uses the __cdecl calling convention. You fix that by putting #pragma managed(push, off) before the #include, #pragma managed(pop) after it.
Trying to link a static library that was compiled with /clr in effect. That's not supported without otherwise drawing a complaint about that when you build the library, unfortunately. The equivalent is already well supported by the CLR, it binds libraries at runtime. You fix that by creating a class library project instead so you'll get a DLL after building it. Use Add Reference to import the declarations from that assembly instead of using #include.
Forgetting to tell the linker that it needs to link an unmanaged static library or import library. Using Add Reference is supported in VS2010 and up, on earlier versions of VS you need to use the Linker, Input, Additional Dependencies setting or use #pragma comment(lib, "name") in your source code.
$$F part of the given mangled name is a marker of function modifier , that means managed function [Managed C++ or C++/CLI], according to "Visual C++ name mangling".
I faced very similar problem. I figured out that in my case there was:
<ProjectReference Include="ProjName\ProjName.vcxproj">
<ProjectReference Include="..\ProjName\ProjName.vcxproj">
I've just fixed that and made rebuild and it helped me.
I was looking over the list of functions that were exported from a dll using depends and i noticed some weird symbols included with the names. They are of the format
??0Function Name##QEAA#AEBV0##Z
Also 0 maybe replaced by some other number.
The number of ## and the alphabets vary.
Can anybody tell what they represent?
That's the name of a C++ identifier that was decorated by the C++ compiler. You can run the undname.exe utility from the Visual Studio Command Prompt to convert it back to the original C++ declaration:
C:\>undname ??0Foo##QEAA#AEBV0##Z
Microsoft (R) C++ Name Undecorator
Copyright (C) Microsoft Corporation. All rights reserved.
Undecoration of :- "??0Foo##QEAA#AEBV0##Z"
is :- "public: __cdecl Foo::Foo(class Foo const & __ptr64) __ptr64"
Which makes it the copy constructor for the Foo class, compiled to 64-bit code. The exact decoration algorithm is not documented that I know of. In general, name decoration is used to avoid linker symbol collisions, necessary because C++ supports overloading. You can suppress decoration by using extern "C" but that can't work on a C++ class.
In some situations you might be interested to undecorate these names programatically using an API Microsoft is providing UnDecorateSymbolName.
trying to wrap a native cpp class using managed c++ class.
all looks good but for some reason it wont compile.
getting the following linker errors:
Error 25 error LNK2028: unresolved token (0A0002CE)
Error 27 error LNK2019: unresolved external symbol
Any ideas how do I fix this one ? :\
well, here is a full error of one of the functions:
Error 20 error LNK2028: unresolved token (0A0002CF) "public: bool __thiscall RCSclient::ResumeChannel(char *,int,__int64)" (?ResumeChannel#RCSclient##$$FQAE_NPADH_J#Z) referenced in function "public: bool __clrcall RCSClientWrapper::RCSclientWrapper::ResumeChannel(class System::String ^,int,class System::DateTime ^)" (?ResumeChannel#RCSclientWrapper#RCSClientWrapper##$$FQ$AAM_NP$AAVString#System##HP$AAVDateTime#4##Z) RCSClientWrapper.obj RCSClientWrapper
Tried to add the user32.lib with no results..
Ofer
C++/CLI allows you
to mix in native C++ pretty much at will, but using C++/CLI makes your app
depend on the .NET framework.
The reason is your C++/CLI project doesn't have some libs (user32.lib, in example) setup in the linker input is that the .NET framework already provides similar services, and the
IDE assumes that you prefer those to the older, native ones.
Check your project and add reference to the corresponding library.
Maybe you forgot an virtual keyword into the native C++ header function declaration
to call from managed wrapper!?