Mike-Ward.Net

Calling Managed Code from C++ Gotcha

Here’s an issue I ran into the other day.

IMarkupServices markup = (IMarkupServices)htmlDocument2;

This line of code was embedded in a C# routine. When called from other C# routines, it worked fine. However, when called from a legacy C++ program it raised an InvalidCastException.

The inner exception of this code reported a COM error of E_NOINTERFACE. Huh? Clearly the documentation says that IHTMLDocument2 contains a reference to IMarkupServices. So what’s happening?

The Gotcha is that many COM (aka ActiveX) controls require single threaded apartment mode. In C#, you can force this by adding the STAThreadAttribute to your entry point as follows:

[STAThread]
static void Main()
{
    Application.EnableVisualStyles();
    Application.SetCompatibleTextRenderingDefault(false);
    Application.Run(new Form1());
}

In C++, you can’t do this if you’re entry point is not managed. Instead, you’ll need to use a linker switch:

/CLRTHREADATTRIBUTE:STA

Setting the correct apartment model allows the cast to succeed.

Adam Nathan’s blog article “Gotcha with STAThreadAttribute and Managed C++” explains why this linker setting is necessary.

← newer older →
.Net, Technology, Life, Whatever

Recent Posts

Checklist Buddy Available for Testing
Tweetz 2.0.0 Released
Tweetz 2.0 Beta
VSColorOutput 2.7 - Time Stamps
Fixed Focal-Length Eyeglasses, a Programmer's Best Friend
How to Choose the Right VPN Service
Two Handy Command Line Scripts
More... (1089)

Donate