2

I have this code in C++/CLI project:

CSafePtr<IEngine> engine;
HMODULE libraryHandle;

libraryHandle = LoadLibraryEx("FREngine.dll", 0, LOAD_WITH_ALTERED_SEARCH_PATH);

typedef HRESULT (STDAPICALLTYPE* GetEngineObjectFunc)(BSTR, BSTR, BSTR, IEngine**);
GetEngineObjectFunc pGetEngineObject = (GetEngineObjectFunc)GetProcAddress(libraryHandle, "GetEngineObject");

pGetEngineObject( freDeveloperSN, 0, 0, &engine )

last line throws this exception:

RPC Server in not available

What may causing this exception?

Václav Dajbych
  • 2,584
  • 2
  • 30
  • 45
  • Which version of ABBYY FRE is it? Do LoadLibraryEx() and GetEngineObject succeed? How exactly do you see the exception? – sharptooth Jul 12 '10 at 11:03
  • ABBYY Fine Reader Engine 9.0 Visual Studio throws me an exception during pGetEngineObject call. – Václav Dajbych Jul 19 '10 at 08:05
  • 1
    Do you mean that the debugger says that ther was an exception thrown? If so - after GetEngineObject() returns use the code you find in check() function to retrieve the IErrorInfo* and description text. That text will explain what's wrong. – sharptooth Jul 21 '10 at 10:32

1 Answers1

2

ABBYY FRE is a COM object. GetEngineObject() behaves like a normal COM interface method except it's a separate function. Which means the following: it doesn't allow exceptions propagate outside. To achieve this it catches all exceptions, translates them into appropriate HRESULT values and possibly sets up IErrorInfo.

You trying to analyze the exception thrown inside a method have no chances to find what the problem is. That's because internally it might work like this:

HRESULT GetEngineObject( params )
{
    try {
       //that's for illustartion, code could be more comlex
       initializeProtection( params );
       obtainEngineObject( params );
    } catch( std::exception& e ) {
       setErrorInfo( e ); //this will set up IErrorInfo
       return translateException( e ); // this will produce a relevant HRESULT
    }
    return S_OK;
}

void intializeProtection()
{
    try {
       doInitializeProtection();//maybe deep inside that exception is thrown
       ///blahblahblah
    } catch( std::exception& e ) {
       //here it will be translated to a more meaningful one
       throw someOtherException( "Can't initialize protection: " + e.what() );
    }
}

so the actual call can catch exceptions and translate them to provide meaningful diagnostics. In order to obtain tha diagnostics you need to retrieve IErrorInfo* after the function retuns. Use code from check() function from the same example project for that. Just don't stare at the exception being thrown - you have no chances with that, let it propagate and be translated.

sharptooth
  • 167,383
  • 100
  • 513
  • 979