Question

I've been finding bits and pieces to this answer on the web, but not a crystal clear solution.

Here's what i'm trying to do. 1) Create an ATL Simple Object. 2) Add a method to that object which returns a BOOL, not an HRESULT. The caller wants true/false return values. 3) Throw an exception to a jscript or vbscript caller that will provide e.description and e.number data.

RE 2) I've found that I can use STDMETHODIMP_(BOOL) along with [local] to allow BOOL to be returned RE 3) I've found that I can pass IErrorInfo via SetErrorInfo() to populate the Error object

My dilemma is I can't figure out how to architect C++ to throw an exception across the ABI boundary that won't crash the caller.

Was it helpful?

Solution

When you write code for a scripting client then you must use a subset of COM called Automation. Which dictates that:

  • all interfaces must be derived from IDispatch
  • a coclass should implement only one source interface
  • all methods must return a HRESULT, only STDMETHODIMP is valid
  • argument types must be restricted to the subset permitted by Automation.

In particular that means that BOOL is not permitted, it must be VARIANT_BOOL. You declare a method that returns a boolean by writing it like this in IDL:

 [id(42)] HRESULT Foo([out,retval] VARIANT_BOOL* retval);

Assign VARIANT_TRUE or VARIANT_FALSE to *retval in your code. The scripting language uses natural syntax like var = Foo().

You generate an exception in the scripting client by returning a failure HRESULT.

OTHER TIPS

You can make the client handle an 'exception' by

  1. setting the IErrorInfo like you said
  2. returning a non HRESULT hr != S_OK

So, you need IDispatch/Interop compatible interfaces, which require HRESULT return types (AFAIR).

IDL allows a lot more, but 'dynamic' clients like script hosts (VBS, JScript, VBA and others) don't consume those natively, so the interoperability will not be optimal.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top