FAQ in daily use of VS2008 and C++/CLI
From CppWiki
This FAQ is based on problems experienced with VS2005 and VS2008
[edit] Q: Before you begin
A: if you're using vs2005 or vs2008 without SPs, you should update to vs2008 SP1 first, this often solves much of the "weirdness" going :) also the project changes needed are often minimal. (I've never had to rework any code to update from 2005)
[edit] Q: Error LNK2022: metadata operation failed when building a solution with multiple projects, when using build (not rebuild)
error LNK2022: metadata operation failed (xxxx) : Inconsistent method declarations in duplicated types error LNK2022: metadata operation failed (xxxx) : Inconsistent field declarations in duplicated types error LNK2022: metadata operation failed (xxxx) : Inconsistent property declarations in duplicated types
Some people have reported this problem as "#pragma once is not working" but it is unclear to me how this could influence incremental linking of metadata.
- A: A full rebuild usually gets rid of this error (undesirable)
- A: make sure intermediate directories for debug/release builds are different!
- A: the problem is caused by a bug in the managed-incremental build system, it can be worked around by switching off incremental builds,
(Set project->Properties->Configuration Properties->General->Enable Managed Incremental Build" to No.)
or replace: [assembly:AssemblyVersionAttribute("1.0.*")];
with: [assembly:AssemblyVersionAttribute("1.0.0.1")];
in AssemblyInfo.cpp. This will ensure that the version does not change between incremental builds.
references: http://connect.microsoft.com/VisualStudio/feedback/Validation.aspx?FeedbackID=114991 http://stackoverflow.com/questions/810827/lnk2022-metadata-operation-failed-driving-me-insane
[edit] Q: Performance of my program seems to go up when i minimize it?!
- A: OnPaint/OnPaintBackground methods aren't called when the window is not visible there might be cpu-intensive things going on there?
[edit] Q: My program hangs when closing it, it appears there are still some threads running?
- A: make sure all threads you create are set t->IsBackground = true; non-background threads will keep the process from stopping (the process will wait for foreground thread to end before dieing). Also if you use support libraries that replace main() (like SDL or ACE), make sure your call any initialization and finalization methods like init() / fini() just once! and be sure to call both!
[edit] Q: My program crashes with an "abnormal program termination" ?!
- A: System::Diagnostics::Debug::Assert seems to do weird things at runtime in release mode (while it should not be doing anything at all in release mode) try to replace all instances with your own MyAssert() method that logs a msg or throws an exception.
void MyAssert(bool expr)
{
#ifdef _DEBUG
// this allows the debugger to break into code
System::Diagnostics::Debug::Assert(expr);
#else
if (!expr)
{
System::Diagnostics::StackTrace ^ st = gcnew System::Diagnostics::StackTrace(Thread::CurrentThread, true);
System::Diagnostics::Debug::WriteLine("assertion failed");
System::Diagnostics::Debug::WriteLine(st);
// optionally: throw gcnew Exception("assertion failed");
}
#endif
}
The diagnostic messages can be caught at runtime by using a OutputDebugString monitor like DebugView
[edit] Q: Why do I get cross thread exceptions
- A: since .NET 2.0 gui controls may not be accessed directly from any thread that is not the thread it (or it's parent) was created on. Rule of thumb: create all controls on the gui thread and only access the controls from the gui thread. ->Invoke() can be used to delegate tasks to the gui thread. For testing purposes the Cross-Thread-Checking can be disabled:
Control::CheckForIllegalCrossThreadCalls = false;
This can also be useful to quickly get .NET 1.0 code working on a .NET 2.0 platform.
[edit] Q: "build to much" problems?
- A: Project dependencies can create what appears to be a "build to much" problem in managed solutions.
(suppose project A depends on project B) The problem is that by creating a project dependency, all .cpp files from project A "depend" on the .dll from project B. (In my opinion this is not correct behavior but VS2008 still seems to think otherwise :) This causes any change, no matter how small in project B to trigger a complete rebuild of project A. This can be worked around by not chosing "build solution" but instead "build project". When you "start debugging" and are asked if you want to build project A because it is out-of-date, you simple choose "no" and it will run without having to build project A. Alternatively: the "Build Project" button can be added to the build-toolbar, and F7 can be associated with "Build Project" futhermore at Tools->Options->Projects and Solutions->Build And Run->On Run, you can set "when projects are out of date" to "Never Build". VS2008 SP1 partially solved this problem with better project-dependancy checking.
[edit] Q: In the express editions, the "UserControl" control type in not available?
- A: officially, you have to buy the VS200X Professional version, unofficially:
create a "Form" using the new item wizard and change "public ref class FooControl : public System::Windows::Forms::Form" to "public ref class FooControl : public System::Windows::Forms::UserControl"
After you re-open the form, it will have turned into a UserControl.
- As a side-note, notice: there is a bug in the Form template for C++, if the namespace is deeper then one level,
namespace Foo.Bar {
is generated instead of
namespace Foo { namespace Bar {
The first is probably valid in C#, but not for C++/CLI.
[edit] Q: After adding a new form visual studio 200x complains about the .resx file "already exists in the project"
- A: the wizard does not always write the file into the right directory (bug), locate it and move it into the same directory as the .h file, after this check the vsproj file and verify the path points to the correct .resx file. (also make sure the .resx file is listed only once)
[edit] Q: At runtime my application complains about a System.Resources.MissingManifestResourceException
- A: check the exact resource that it names, use Lutz Roeder's reflector tool to see where the resource its looking for really is. The place resources are embedded can be altered at .resx-file's Properties. The "Resource File Name" is where the resource will be embedded at compile time, it usually contains something like:
$(IntDir)\$(RootNamespace).$(InputName).resources, check under "Commandline" what this actually resolves to.
Sometimes you may want to add extra levels after "$(RootNamespace)" so for example:
$(IntDir)\$(RootNamespace).UserControls.$(InputName).resources
- A: moving a customcontrol's sources files into a different directory will causes this problem, different people mention change the "default namespace" in project settings, but I have not been able to find this.
- A: In C# you cannot declare any other enums/classes above the custom control! (will cause the MissingManifestResourceException at runtime) but C++/CLI does not seem to have this limitation.
[edit] Q: I've installed a catch-all try/catch around main() but still some errors cause unhandled exceptions!?
- A: Remember that exceptions should be handled were they occur, so a try/catch around main is never a solution to anything, the problem will still occur, only the program will not end (immediately), still could possibly cause even more damage/errors to occur. That said, for debugging/logging the technique is very useful, but the catch-all try/catch should be installed separately for each thread you start, not just the main thread.
[edit] Q: an exception occurs in a remoting calls with the message "The Undo operation encountered a context that is different from what was applied in the corresponding Set operation"
"The Undo operation encountered a context that is different from what was applied in the corresponding Set operation" occurs in remoting calls (also seen as "An unhandled exception of type 'System.InvalidOperationException' occurred in mscorlib.dll" with a stack-trace in non-user code during the return from a remoting-call sometimes)
- A: Application::DoEvents() in a remoting call is often the cause of this problem, interacting with the GUI in remoting calls does not seem like a good idea to me. I think a CrossThread exception would have been more informative in this case. As a workaround, don't interact with the GUI thread in remoting-calls. (use ->Invoke() instead if you must).
[edit] Q: the designer reports an error and your component class cannot be visually edited anymore
For instance: Catastrophic failure (Exception from HRESULT: 0x8000FFFF (E_UNEXPECTED)) and the stacktrace shows: at EnvDTE.CodeFunction.GetStartPoint(vsCMPart Part)
Or: ....must implement IConvertable
A: Perhaps the most annoying kind of error, it happens randomly and is not reproducible. It is can often be solved by reverting changes you made to the .h file involved (even if it is just whitespace or changes in the order of declarations). If that doesn't help, delete the intellisense and other temporary files and rebuild the solution. (delete *.obj *.suo *.ncb *.pch *.dep *.idb *.meta)
--Skyhawk 04:57, 30 January 2009 (EST)
