0
votes

I am working on an ATL project in Visual Studio which exposes a COM object which defines a structure.

I have the following COM method defined in my *.idl:

[id(2)] HRESULT CheckOut([in] CHAR* feature, [in] CHAR* version, [out] CerberusCheckoutDetails* details, [out] CerberusErrorDetails* error);

My *.idl defines this structure:

[
    uuid(527568A1-36A8-467A-82F5-228F7C3AC926),
    version(1.0)
]
typedef struct CerberusErrorDetails {
    INT ErrorCode;
    BSTR ErrorMessage;
} CerberusErrorDetails;

My implementation returns this structure at some point:

int result = checkout(feature, version, 1, 0, remoteServerName);
if (result != 0)
{
    error = new CerberusErrorDetails();
    error->ErrorCode = result;
    error->ErrorMessage = _bstr_t(errstring()).Detach();
    return result;
}

I call it like this:

CerberusNativeLib::CerberusErrorDetails *error = new CerberusNativeLib::CerberusErrorDetails();
if (session->CheckOut(feature, version, details, error) != S_OK)
            std::wcout << error->ErrorCode << ": " << error->ErrorMessage << std::endl;

My issue is that error->ErrorCode is 0 but it should be -95 (stepping through the code, I can see that result is -95) and error->ErrorMessage is always NULL but it should contain an actual error message as errstring() returns a char * which is filled, such as Error trying to connect.. Why is that? I want to return a structure. Do I have to allocate it in some special way from the calling side or from the COM object side? Can someone provide an example of how to do this please?

1

1 Answers

2
votes

Without a complete example, it's hard to know exactly what you're trying to do. But it would appear that you may want to write the following

CerberusNativeLib::CerberusErrorDetails error;
if (session->CheckOut(feature, version, details, &error) != S_OK)

(no new, address of struct on the stack passed) and

int result = checkout(feature, version, 1, 0, remoteServerName);
if (result != 0)
{
    error->ErrorCode = result;
    error->ErrorMessage = _bstr_t(errstring()).Detach();
    return result;
}

(again, no new). Notice this has little to do with COM.