C++/CLI usage with unmanaged code - Boost, <future> - c++

I am trying to compile a C++ library for use with C# on Windows (the library is Vanetza).
The library uses CMake, I am building from Microsoft Visual Studio Community 2022 (64-bit). I can build the library as shared DLL no problem. For use with C#, I thought of compiling the library as C++/CLI (common language runtime support enabled). At first, I could not compile it because the project uses Boost, but some compilation issues were solved by surrounding every Boost include with #pragma managed(push, off) and #pragma managed(pop).
Issue which blocks me now is that <future> header cannot be used with C++/CLI - I am getting this compilation error from lot of different places:
Severity Code Description Project File Line Suppression State
Error C1189 #error: <future> is not supported when compiling with /clr or /clr:pure. geonet C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\MSVC\14.33.31629\include\future 13
and I cannot solve this. I think that some Boost module that is used needs this header.
Is there any solution to this or is there another approach that could be used?
I need not only to get to some C++ functions of the library, but also to use some of its classes and to see some of its structures.
I tried compiling the library as normal C++ and then make an interfacing C++/CLI library which would be called from C#, but the header is again used somewhere.
I think that using P/Invoke (DLLImport) is impractical for me as it is only making possible to use C/C++ functions, but for classes and structures it cannot be used (as I understand it).
Is only possible solution to rewrite the parts that need <future> myself using C# constructs as mentioned in this question?
As per other similar questions, it seems that sometimes the project can be built such that Boost works without any problems and sometimes major code rewrite is needed. Could someone recommend me what would a usable approach would be in my case? I could use older Boost version (namely 1.58.0), but I do not know if it would help.

Write a class in c++/cli that connects to your C++ code. The code will call the router which I presume will return a future. Then in manged/cli you create a task that hooks up to that future. So you have the original code compile to a static C++ lib and link that into your managed C++/cli dll

Related

Error C2711 building DLL from a C++ project that uses tbb

I'm trying to build some dll to wrap some Computer Vision methods in a c++ software to use them a c# software, and I need to call some tbb (Threading Building Blocks) methods from the c++ methods to process some frame. I'm developing in CLR using Charset Unicode, in visual studio, and once I call the tbb header
#include <tbb/tbb.h>
The compiler give me the error:
error C2711: 'tbb::internal::concurrent_vector_base_v3::concurrent_vector_base_v3' try use #pragma unmanaged;
I've correctly imported and linked libraries and headers files, and the required dlls.
I've looked for some helps on Intel's forums but I found nothing.
This sounds like you're trying to build an application using CLR, but it doesn't like some of the code in tbb's header. Error C2711 happens when trying to compile code as managed that it is unable to manage (for example, using inline assembly).
If you don't need CLR, you should just be able to disable it (remove /clr) -- which should fix this warning. Otherwise, you can use #pragma unmanaged as recommended in the warning to disable it -- I'm guessing before the inclusion of the tbb/tbb.h header. Something like:
#pragma managed(push, off)
#include <tbb/tbb.h>
#pragma managed(pop)
This should tell the project that any code in tbb.h (such as potentially inline functions that use assembly) should not emit IL.
Possibly related are some answers to this question which describes how interfacing with native code in CLR projects is commonly done

How to implement a unmanaged thread-safe collection when I get this error: <mutex> is not supported when compiling with /clr

I have a C++ application which consists of unmanaged C++, managed C++ and c#. In the unmanaged part I'm trying to create a thread safe collection using std::mutex.
However when I use the mutex I get the following error;
error C1189: #error : <mutex> is not supported when compiling with /clr or /clr:pure.
Any idea why I can't use the mutex?
Can someone recommend a replacement for it so that I can create a thread-safe unmanaged collection?
It is not supported because the std::mutex implementation uses GetCurrentThreadId(). That's a winapi function that is not supposed to be use in managed code since it might be running on a custom CLR host that doesn't use threads to implement threading.
This is the good kind of problem to have, it shows that you are building your code wrong. Your native C++ is being compiled with /clr in effect. Which works rather too well, all C++03 compliant code can be compiled to MSIL and get just-in-time compiled at runtime, just like managed code. You don't want this to happen, your native C++ code should be compiled to machine code and get the compile-time code optimizer love.
Turn off the /clr option for this source code file, and possibly others, in your project. Right-click + Properties, General. If the mutex appears in the .h file that you have to #include in a C++/CLI source file then you have a bigger problem, use an interface or pimpl to hide implementation details.

Use C++ DLL in .NET

I asked this question yesterday about using the Cygwin compiler to produce a C++ DLL that can be used by .NET: Using C++ app in .NET
The solution was to compile the C++ application using Visual C++ rather than Cygwin i.e. I was able to call a C++ function from .NET.
Why am I able to do this in Visual C++ and not Cygwin? The code can be found in my linked question. Here is a screen shot of Dependancy Walker for the Visual C++ DLL in case it helps answer my question:
Name mangling schemes are different in gcc/mingw/cygwin and msvs. You'll have to use the pure-C interface if you want to share DLLs between compilers.
Alternatively, you could use .def files as is described in the bottom answer to this question: How to use libraries compiled with MingW in MSVC?

MS vs Non-MS C++ compiler compatibility

Thinking of using MinGW as an alternative to VC++ on Windows, but am worried about compatibility issues. I am thinking in terms of behaviour, performance on Windows (any chance a MinGW compiled EXE might act up). Also, in terms of calling the Windows API, third-party DLLs, generatic and using compatible static libraries, and other issues encountered with mixing parts of the same application with the two compilers.
First, MinGW is not a compiler, but an environment, it is bundled with gcc.
If you think of using gcc to compile code and have it call the Windows API, it's okay as it's C; but for C++ DLLs generated by MSVC, you might have a harsh wake-up call.
The main issue is that in C++, each compiler has its own name mangling (or more generally ABI) and its own Standard library. You cannot mix two different ABI or two different Standard Libraries. End of the story.
Clang has a specific MSVC compatibility mode, allowing it to accept code that MSVC accepts and to emit code that is binary compatible with code compiled with MSVC. Indeed, it is even officially supported in Visual Studio.
Obviously, you could also simply do the cross-DLL communication in C to circumvent most issues.
EDIT: Kerrek's clarification.
It is possible to compile a large amount of C++ code developed for VC++ with the MinGW toolchain; however, the ease with which you complete this task depends significantly on how C++-standards-compliant the code is.
If the C++ code utilizes VC++ extensions, such as __uuidof, then you will need to rewrite these portions.
You won't be able to compile ATL & MFC code with MinGW because the ATL & MFC headers utilize a number of VC++ extensions and depend on VC++-specific behaviors:
try-except Statements
__uuidof
throw(...)
Calling a function without forward-declaring it.
__declspec(nothrow)
...
You won't be able to use VC++-generated LIB files, so you can't use MinGW's linker, ld, to link static libraries without recompiling the library code as a MinGW A archive.
You can link with closed-source DLLs; however, you will need to export the symbols of the DLL as a DEF file and use dlltool to make the corresponding A archive (similar to the VC++ LIB file for each DLL).
MinGW's inclusion of the w32api project basically means that code using the Windows C API will compile just fine, although some of the newer functions may not be immediately available. For example, a few months ago I was having trouble compiling code that used some of the "secure" functions (the ones with the _s suffix), but I got around this problem by exporting the symbols of the DLL as a DEF, preparing an up-to-date A archive, and writing forward declarations.
In some cases, you will need to adjust the arguments to the MinGW preprocessor, cpp, to make sure that all header files are properly included and that certain macros are predefined correctly.
What I recommend is just trying it. You will definitely encounter problems, but you can usually find a solution to each by searching on the Internet or asking someone. If for no other reason, you should try it to learn more about C++, differences between compilers, and what standards-compliant code is.

Unmanaged C++ libraries - differences between VS2005 and VS2008?

I'll preface this by saying I'm a C# programmer who inherited horrible code with no documentation. I have an unmanaged C++ library wrapped with managed code that worked fine in VS2003 with .Net 1.1 Framework. I'm trying to get it upgraded to at least .Net 2.0.
I have the unmanaged C++ library that was compiled with "MSVC 8.x" (thus equivalent to VS 2005, I assume). I've been trying to migrate everything to VS2008 and still have some issues with this library at runtime.
My question is this: should this library work with VS2008? Or should I be developing in VS2005 if the library was compiled with VC8.x?
Any thoughts would be greatly appreciated. Thanks!
It should work, I expect that you are having issues with your marshalling. It is probably stuff that was declared incorrectly for PInvoking that managed to work in .NET 1.1 but not in later versions.
You don't say what sort of problems you are having at run time, nor do you state how you access your library. For example, do you compile your library along with your project? If so, can you turn on unmanaged debugging in your C# project and step into the code you are having trouble with? How are you calling the unmanaged code? Is it through PInvoke, or do you have managed C++ wrappers?
In my experience, the best solution for calling out to a legacy unmanaged library is to add a managed wrapper library for your legacy library written in managed C++. This way you present a managed interface for your library for all .NET languages to consume and you don't have to worry about getting your PInvoke signatures correct.
Your project should look something like this.
C# Application -> Manage C++ Wrapper DLL -> Legacy DLL
It can depend what else the lib relies on. For example, if you are using the STL across the library interfaces then it would be a bad idea to have the library compiled with a different version to the client. However, if the library presents a simple C style function interface then you shouldn't have problems.
If you have the source code for the library then I would recommend trying to port it to VS2008. In general it is much less hassle in the long run to have everything in the same development environment.
How are you wrapping the unmanaged lib ... presumably using managed extensions for C++ if it dates back to VS2003. This is now deprecated and has been replaced with C++/CLI as of VS2005. Whilst the newer compilers support a /clr:oldSyntax switch to still compile the old code there are definitely issues with it. We have old code that will not compile on VS2005(8) using this switch.
--Rob Prouse:
The wrapper uses managed C++, no PInvoke. The wrapper is compiled into a DLL that is then used by another application (as you illustrated).
The legacy code produces graphics objects. When I try to get the handle to an image, I get a null exception instead. The debugger doesn't let me get farther into the code to figure out why. Everything else seems to run ok - the other data objects needed to create the image exist and appear to be correct. (Sorry, I know that is still a pretty vague description.)
--Rob Walker:
I unfortunately do not have the source code.
Not sure about "using the STL across the library interfaces". Does graphics fall under that category?
I was able to get my application to run with using the /clr:oldSyntax switch, but that's where I get the null handles to images. I tried to put in all the modifications so that it would compile with /clr, but then I kept getting link errors that I couldn't resolve. (The linker kept complaining about not being able to find files even though those files were in the folder where it was looking.)