Tag Archives: COM

.NET 4.0 Type Equivalence causes BadImageFormatException

I recently discovered a nasty backward compatibility problem with the new type equivalence feature in .NET 4.0. Luckily it’s relatively difficult to hit it if you’re in a pure-C# environment, but if you happen to generate any assemblies directly using IL, you should watch out. Read on for all the gory details.
Continue reading .NET 4.0 Type Equivalence causes BadImageFormatException

Beware of using stack-based COM objects from .NET

There are all sorts of nasty things to be aware of if you’re mixing reference-counted COM objects with garbage-collected .NET. For instance, if you’re implementing COM objects in C++ then you’re free to allocate them anywhere you like; on the heap or perhaps on the stack if you know they’re only used in some specific scope.

But what happens if during the lifetime of that stack based COM object, it gets used from .NET? A runtime callable wrapper (RCW) will be created around the object. And this RCW expects to be able to keep the underlying object alive by incrementing its reference count. Of course, the stack-based object will soon go out of scope, and regardless of its reference count the object will be destroyed and the pointer that the RCW contains will no longer be valid. It points into the stack, so when the RCW gets cleaned-up, the CLR will call via this pointer into memory that contains garbage and you’ll get something nasty like an access violation or illegal instruction exception.

Continue reading Beware of using stack-based COM objects from .NET

Don’t do anything in DllMain… Please

Novice Windows programmers can often think that DllMain is a good place to get that one-time set-up and tear-down work done. It seems to offer an ideal opportunity to know when your DLL has just been loaded, and when it’s about to be unloaded. What better place to add all that expensive, complicated initialisation…? STOP! WAIT! Before you add anything in DllMain, make sure you understand what state the process will be in when it gets called. Once you know that, you may well change your mind…
Continue reading Don’t do anything in DllMain… Please

Getting IUnknown from __ComObject

I’m working in an environment with a lot of mixed managed (F#) and unmanaged (C++ COM) code. One of the big problems with this is the mix of lifetime management techniques; .NET uses garbage collection while COM relies on reference counting. Furthermore .NET garbage collection is somewhat non-deterministic, which adds further complexity.

So quite often in our mixed code-base, we find that the .NET garbage collection process doesn’t kick in when we need it to. For instance, when we’ve allocated a lot of memory in the COM code that .NET isn’t aware of. Memory exhaustion has to get pretty bad for the GC to occur at any other time than during a .NET allocation, either the system-wide low-memory event has to be signalled or an OutOfMemoryException needs to be thrown. In both of these cases it’s probably too late to do anything about it.

In this case it’s extremely useful to be able to see what .NET objects are still alive, and what COM objects they’re hanging on to. Unfortunately this isn’t as easy as it might seem.
Continue reading Getting IUnknown from __ComObject

Getting .NET type information in the unmanaged world

One of the tools that I write and maintain displays type information for COM objects hidden behind “handles” in Excel spreadsheets. The underlying objects can either support an interface that allows them to be richly rendered to XML, or the viewer will fall-back to using metadata and displaying the supported interfaces and their properties and methods. It will also invoke parameterless property getters – making the assumption that doing so won’t change the state of the object – and display the returned value. This is a useful way of getting some visibility on otherwise completely opaque values.

In order to obtain the type information about the COM objects, the tool uses type libraries, and the associated ITypeLib and ITypeInfo interfaces, which, with a little effort, can be used to iterate over all the coclasses, interfaces and functions in the library. But the difficulty lies in obtaining a type library when all you’re given is an already-instantiated object. In theory, COM allows you to know no more about an object than what interfaces it supports. But in practice, there are a variety of ways you can circumvent this and get to the type information.

For unmanaged COM objects you can use the information in the registry (or SxS configuration) and obtain the server (DLL) that contain a TLB embedded as a resource, or the type library filename itself. I won’t go into that now, there’s plenty of information about the location of these common registry keys elsewhere on the internet.

But for managed COM objects – well, COM callable wrappers (CCWs) – you have a different problem: registry scraping will never work and there may not even be an associated type library. The InprocServer32 registry entry always points to mscoree.dll, which obviously doesn’t have an embedded type library, and unless you’ve registered the assembly with /tlb (which is a pain) then you won’t have entries under HKEY_CLASSES_ROOT\Typelib and a TLB file to load.

So, if you’re in the unmanaged world, and all you’ve got is a pointer to a live CCW, what can you do?

Well, the easiest thing is to use IProvideClassInfo. This is supported by all CCWs, and provides a way to get an auto-generated (by the CLR) ITypeInfo implementation for the managed class. In fact, this is what I actually used to implement the solution eventually, but along the way I discovered some other interesting aspects of the CCW.

There is another interface that it supports: _Object, the unmanaged version of System.Object, which supports basic .NET functionality such as ToString and GetType. I couldn’t find it declared anywhere in the Platform or .NET SDK headers, so I put together a version that I could use from C++:

struct __declspec(uuid(“{65074F7F-63C0-304E-AF0A-D51741CB4A8D}”)) Object : public IDispatch

{

public:

// We don’t actually call these methods, doing so seems to return

// COR_E_INVALIDOPERATION. Instead we just use the IDispatch::Invoke

// and use the DISPID of the methods.

virtual HRESULT STDMETHODCALLTYPE ToString(BSTR *) = 0;

virtual HRESULT STDMETHODCALLTYPE Equals(VARIANT, VARIANT_BOOL *) = 0;

virtual HRESULT STDMETHODCALLTYPE GetHashCode(long *) = 0;

virtual HRESULT STDMETHODCALLTYPE GetType(mscorlib::_Type **) = 0;

};

Despite the presence of the virtual functions in this “interface”, we’re not actually going to call them. Instead we’ll call through the IDispatch that it derives from. It may be possible to use them directly, but see the comment describing what happens when I tried it. Calling via IDispatch may seem slightly odd, because the object itself claims not to support it (QueryInteface returns E_NOINTERFACE).

The methods on the _Object interface have well-known DISPIDs:

ToString 0x00000000
Equals 0x60020001
GetHashCode 0x60020002
GetType 0x60020003

So we can use that to invoke the GetType method:

DISPPARAMS parms;

parms.cArgs = 0;

parms.cNamedArgs = 0;

_variant_t vType;

hr = pObject->Invoke(0x60020003, IID_NULL, 0, DISPATCH_METHOD, &parms, &vType, NULL, NULL);

And we get back a _Type interface that allows us to navigate around the type information in the same way as we can with System.Type! Just #import mscorlib.tlb and you get all the interfaces you need to e.g. iterate over all the interfaces implemented by a type, and invoke a function on them:

#import <mscorlib.tlb> rename(“ReportEvent”,“xReportEvent”)

mscorlib::_TypePtr t(V_UNKNOWN(&vType));

CComSafeArray<LPUNKNOWN> saInterfaces(t->GetInterfaces());

mscorlib::_TypePtr tInterface((LPUNKNOWN)saInterfaces.GetAt(n));

result = tInterface->InvokeMember(_bstr_t(“Function”),

(mscorlib::BindingFlags)

(mscorlib::BindingFlags_GetProperty +

mscorlib::BindingFlags_InvokeMethod +

mscorlib::BindingFlags_Public +

mscorlib::BindingFlags_Instance +

mscorlib::BindingFlags_IgnoreCase),

NULL, _variant_t(punk), NULL, NULL, NULL, NULL);

So this turns out to be quite nice: you can get rich managed type information even if you’re running in the unmanaged world.

F# – A little gotcha with GuidAttribute

Be careful when using the [<Guid(“…”)>] attribute on your COM-visible classes in F#. If you mistakenly use the curly-bracket delimited format for the GUID, regasm will silently, yes, silently, fail to add any CLSID entries for your class. That means it will be cocreatable by the prog ID, but not the CLSID. Ouch.

No doubt this will be addressed in the CTP release, due in a couple of weeks.