Things mom never told you about C++ CLI

For the last few months I’ve been working on a project that utilizes C++/CLI to bridge some legacy code with new code written in C#. A good chunk of that time has been spent running repeatedly into walls, pitfalls, quirks, and “known issues.” I figured I’d document some of the issues I’ve encountered in case someone out there to hopefully save people out there a few hours of frustration.

0) Preparation

  • The following are the books I’ve located dedicated to C++ CLI. The biggest problem with these books is they cover very simple scenarios and assume things “just work” when in reality they DON’T quite often and you end up on Google and Stack overflow trying to figure out some cryptic error message.

1) Avoid Visual Studio 2012 Update 2

If you’re doing C++/CLI work Update 2 is the devil! It breaks the mixed mode debugger. Relevant links:

As a side note, XP Compatibility compilation is now broken:

And last but not least uninstalling Update 2 *may* leave your Visual Studio install crippled:

 

1) Compile time and link time errors

Some of these could depend heavily on exactly what you are doing so though you may get the same error you may have a completely different problem/solution. Contact me if you have an issue+solution you’ve discovered and want added.

A) Error: “String cannot be of zero length. Parameter name: frameworkName”

Cause: incorrectly created file located at C:\Users\YOURNAME\AppData\Local\Temp\.NETFramework,Version=v4.0.AssemblyAttributes.cpp

Fix1: The file should be written every build, so just delete teh file

Fix2: Open the file and confirm first parameter is empty string ( L""). If so then add appropriate framework to first parameter, as shown below in red:

#using <mscorlib.dll>
[assembly: System::Runtime::Versioning::TargetFrameworkAttribute(L".NETFramework,Version=v4.0", FrameworkDisplayName=L".NET Framework 4")];

Answer found here: http://stackoverflow.com/questions/13315940/apps-exe-file-missing-net-targetframework-but-only-on-clean-builds

 

B) Error: “String cannot be of zero length. Parameter name: frameworkName”

Cause: incorrectly created file located at C:\Users\YOURNAME\AppData\Local\Temp\.NETFramework,Version=v4.0.AssemblyAttributes.cpp

Updating C++ project to VS2012

I’m currently working on updating one of our core projects to compile on Visual Studio 2012. These upgrades can sometimes be seamless. More often than not, though, there’s some issues that have to be resolved manually. Posting this up in hopes it might save someone out there some time if they’re hitting the same issues.

Item 0:

Before anything else it’s worth taking a look at the C++ breaking changes in VS2012. If I had done this first thing I would have saved some time trying to figure out why I couldn’t find afxcomctl32.h. The answer is it was removed.

Removed Fusion support (afxcomctl32.h); therefore, all methods that are defined in afxcomctl32.h have been removed. Header files afxcomctl32.h and afxcomctl32.inl have been deleted.

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

You can find for more information on activation contexts at http://msdn.microsoft.com/en-us/library/aa374153(v=vs.100).aspx

Item 1: Solution Configuration Combo Box

This one is just an annoyance, but worth posting up. The VS2012 standard bar doesn’t have an obvious way to resize the Solution Configuration combo box.

I was able to find the solution to the problem here:

 

Item 2: Error CA0053

Visual Studio 2010 apparently hard-codes some paths which cause issues for projects being upgraded. Solution info is here:

Item 3: makehm.exe errors

We have a custom build step that runs makehm.exe at the end of the build process. It kept generating an error and reporting that it was unable to open the output file. It looks like it’s just a bug with the program. It’s easy enough to work around by not specifying output and just using redirection to dump stdout output to a file. So instead of:

makehm.exe input_parameters_here output_file

change your command to

makehm.exe input_parameters_here > output_file

Item 4: warning RC4011: identifier truncated to ‘_CRT_SECURE_CPP_OVERLOAD_STANDA’

This error is caused by non-standard #include directives in your .rc files. In my case there was an “#include richedit.h” that was generating the issue. If not for Google this might have proved very difficult to track down as there is no clear indication what the culprit is. As you’ll find in the first link below:

RC files usually just include resource.h (which is just a list of #defines for control identifiers in your dialogs, etc.) and afxres.h (which includes winres.h and is like a cut-down version of the windows

Reference:

Item 5: SAFESEH

The error at hand is “error LNK2026: module unsafe for SAFESEH image.”

Apparently when the project was upgraded the switch was turned on whereas previously the project had contained no value for this Advanced Linker switch.

 

If /SAFESEH is not specified, the linker will produce an image with a table of safe exceptions handlers if all modules are compatible with the safe exception handling feature. If any modules were not compatible with safe exception handling feature, the resulting image will not contain a table of safe exception handlers.

http://msdn.microsoft.com/en-us/library/9a89h429(v=vs.110).aspx

So you can either rebuild the libraries responsible for the error or you can disable it for the project you are building. Be aware there may be security implications to consider if you decide to turn the switch off. You can do so by going to the properties for the project and under Linker->Advanced the very last item should be “Image Has Safe Exception Handlers.” You can explicitly disable or just delete the entry to rely on default behavior.

 Item 6: Casting Errors

This post at Stack Overflow captures my issue. Essentially a casting operation that was working in VS2010 stopped working when I tried to compile the exact same code in VS2012.

C++ Compile Error in Visual Studio 2012: LPCWSTR and wstring

Coming soon:

 Item X: BuildShadowTask

 

TIL: About Visual Studio C++ and ‘for each in’

Most C++ developers are familiar using with for_each() when iterating over an STL collection. But a few months ago as I read a blog post about the ‘auto’ keyword over at Marc Gregoire’s Blog I was dumbstruck when saw the following example:

[sourcecode language=”cpp”]
for each (auto m in myMap)
{
tcout << _T("Map element ") << m.first << _T(": ");
for each(auto e in m.second)
{
tcout << _T("'") << e << _T("', ");
}
tcout << endl;
}
[/sourcecode]

What the heck was this ‘for each’ without an underscore business? Apparently I’d been painfully unaware of this new syntax since 2004!!! It’s Microsoft/Visual Studio specific. But since my primary project is Windows-based through and through, you can bet I’ll be making use of this beauty to keep my code cleaner.

-CM12

PS. Do note, though, that this syntax automatically dereferences iterators, so it’s not useful if you need to do iterator manipulation.