Posts

Converting between std::string and .NET System::String in C++/CLI

In the software development world it seems that we spend most of our time converting from one data representation to another…..

So with that in mind, Here is a vary handy cheat sheet for how to go about converting to and from standard strings and .NET System::String when using C++/CLI/CLR:

http://msdn.microsoft.com/en-us/library/bb384865.aspx

Note that the include paths must be pre-pended by “msclr”, e.g.:

#include 

And the symbols live in this namespace: msclr::interop

std::string std_str = msclr::interop::marshal_as(sys_str);

When you #include these headers you may get loads of crazy compile errors, some involve ‘IServiceProvider’, to get rid of these try changing the include order of your headers, you may have to move these marshal includes up closer to the top of your include list.

Can I use std::thread from a C++/CLI project in Visual Studio 2012

This question seems to produce some confusing and contradicting answers, however the short answer to it is ‘yes, you can’.

You can use std::thread in unmanaged code in a C++/CLI project but not from managed code – but the good thing about C++/CLI is that you can mix managed and unamanaged code.

if you try to use it from managed code you will get an errors like this:

error directive: is not supported when compiling with /clr or /clr:pure.

and this:

error directive: ERROR: Concurrency Runtime is not supported when compiling /clr.

To mark a C++ file as un-managed, go to its C/C++ settings and set its ‘Common Language RunTime Support’ setting to ‘No Common Language RunTime Support’. You can also use the ‘managed’ and ‘unmanaged’ pragmas in your code to do the same, but something about mixing the two in a single file creeps me out!

Possibly the best thing to do is to keep managed code to a minimum (as it’s as ugly as sin) and just use it to interface your .NET code to your native C++ code – which can use std::thread et al. to its heart’s content!

.NET C++/CLI – C3145, global or static variable may not have managed type

If you are trying to use a cheeky file static or global variable while eagerly developing your C++/CLI software you will probably encounter the following error:

 

“C3145, global or static variable may not have managed type”

 

At this point you remember that this isn’t really C++ but a crazy non-standard extension to C++! So instead of declaring a file static scope variable like this:


static Acquisition::IImage^ simage = nullptr;

So as a fix, you can declare a container class and add it as a static member, thus:


ref class ImageContainer {
   public:
        static Acquisition::IImage^ Image = nullptr;
};

And then access it in this way:


ImageContainer::Image = image;

Thus solution worked well for us, but of course we will be getting rid of this global variable in due time! ;)

Using OpenCV from .NET C++/CLI

I am happy to report that I have had a reasonably easy run of using OpenCV from a .NET C++/CLI project, I was initially worried that the two might not play well together, but so far – so good! I am wrapping some machine vision code that uses OpenCV in a C++/CLI assembly so that I can call it from C# code. I have kept the rather creepy CLI stuff to a minimum it just implements the interface, everything else is vanilla C++ using the standard library.

 

The only thing I had to do to get rid of build errors was to make sure that each _proper_ C++ file in the project had the following value for the ‘Common Language RunTime Support’ build setting -> ‘No Common Language RunTime Support’!

 

So if you are toying with the idea of developing some OpenCV based software from within C++/CLI, I say give it twirl it makes interacting with .NET much easier than (say) using COM or similar!

 

Breakpoints Not Working / .NET C++/CLI

I was having some trouble getting Visual Studio 2010 to stop at breakpoints in some unmanaged C++ code that’s in a C++/CLI project that I am working on, and as we all know Software Developments rapidly stops being fun if your debugger is broken!

I am using C++/CLI as a thin wrapper around this vanilla C++ functionality so that I could export it to .NET. All was working fine except that the breakpoints in the C++ code did not work. After some searching I found this post:

http://rhnatiuk.wordpress.com/2010/11/13/managednative-debugging-in-cc

The post suggested that I should set the ‘Enable unmanaged code Debugging’ setting of the start-up project (not the C++/CLI project), so I enabled it and the brakepoints started working fine – so big thanks Roman for the tip!