Jim Fell
Jim Fell

Reputation: 14256

C++ DLL Throws Exception at Runtime

My C# application calls a function in a C++ DLL at run-time and throws an exception. The error code generated is 262. Unfortunately, the Microsoft documentation is a bit lacking for this code.

Oddly, this exception is not thrown when running the DLL from the C++ test application that is part of the same Visual Studio solution as the DLL (separate project). (The C# application is in an entirely separate solution.) The error code is returned by a call to CoInitializeEx, which initializes the COM and is the first step my application uses to query the WMI.

The only other thing seems to be related is when I open the DLL with Dependency Walker I get these error and warnings:

Error: At least one required implicit or forwarded dependency was not found.
Warning: At least one delay-load dependency module was not found.
Warning: At least one module has an unresolved import due to a missing export function in a delay-load dependent module.

The only thing that occurs to me is that the missing "required implicit or forwarded dependency" has what is needed ot make CoInitializeEx work. According to Dependency Walker, these modules could not be found:

Any thoughts or suggestions are appreciated. Thanks.

Upvotes: 2

Views: 2877

Answers (5)

Elvedin Hamzagic
Elvedin Hamzagic

Reputation: 855

Error WIN32=262 is HRESULT=-2147024634 (0x80070106). This is something else. CoInitializeEx should be called for every thread only once, but if it is called more than once, there should be one CoUninitialize for every CoInitializeEx.

Upvotes: 0

Euro Micelli
Euro Micelli

Reputation: 33998

In your specific scenario, a separate thread is probably the best thing at your disposal.

Creating threads from a DLL is a messy business because a DLL doesn't own the process' lifetime; the owner is the EXE.

However... if you run it in a synchronous fashion (create the thread; initialize; wait on the thread to complete; then continue), you will generally be safe. You could cache the thread, so you don't have to create and CoInitialize() it every time, but don't let it do work in the background and return to your caller: again, subtle lifetime issues arise.

Upvotes: 1

Hans Passant
Hans Passant

Reputation: 941218

Your error handling isn't kosher, the real error you are probably getting is 0x80010106, the last word is 262. The error code is RPC_E_CHANGED_MODE, "Cannot change thread mode after it is set". Which is what CoInitialize/Ex returns when it was called before and you are trying to change from STA to MTA or the other way around.

This isn't possible, the apartment state for a thread is locked in on the first call to CoInitializeEx(). You need to find out where the first call happened. This could have been done by the CLR for a managed thread for example. The apartment state for a thread is determined by the [STAThread] or [MTAThread] on the Main() method for the startup thread. Or the Thread.SetApartmentState() for a managed thread that you create yourself. A threadpool thread is always MTA, that cannot be changed.

Altering the apartment state for a thread can have many side effects.

Upvotes: 4

Goz
Goz

Reputation: 62323

I assume you don't have Visual Studio 2008 C++ installed as then you'd have MSVCR90D.dll This dll is a debug only dll which means you are trying to load a DLL that has been compiled as a debug DLL.

As for the others ... see this thread: Dependency Walker reports IESHIMS.DLL and WER.DLL missing?

Upvotes: 1

JimR
JimR

Reputation: 16113

Check that you have compiled everything in either release or debug mode.

Do you use any of the http based functionality from I.E? I'm curious why you're dependent on ieshims.dll.

Upvotes: 0

Related Questions