I'm trying to update an existing COM API to include a new optional output parameter, and have run into an issue with the enforced ordering of parameter types in the IDL file and the associated C++ header file.
Previously I had an IDL file like this (names changed to protect the innocent):
HRESULT CreateSomething(
[in] BSTR base_uri,
[in] ISomethingDescription* something_description,
[out, retval] BSTR* something_uri
);
and the associated C++ header looked like:
HRESULT __stdcall CreateSomething(
/* [in] */ BSTR study_uri,
/* [in] */ ISomethingDescription* something_description,
/* [out, retval] */ BSTR* something_uri
);
This needed to be updated to add an optional output parameter that could provide some clients with extra error reporting information, following an existing pattern against the rest of the in-house SDK.
To do this I was planning to update the IDL file to look like this:
HRESULT CreateSomething(
[in] BSTR base_uri,
[in] ISomethingDescription* something_description,
[out, defaultvalue(0)] ErrorCode* error_code,
[out, retval] BSTR* something_uri
);
Where ErrorCode is an enum defined in a separate IDL file. This follows the guidance I have seen online about how parameters with defaultvalue and retval attributes should be ordered. However, when I then try to upate the C++ header file, I run into the issue that the default parameter is not at the end of the parameter list, i.e.
HRESULT __stdcall CreateSomething(
/* [in] */ BSTR study_uri,
/* [in] */ ISomethingDescription* something_description,
/* [out, defaultvalue(0)] */ ErrorCode* error_code = 0, // this is clearly wrong
/* [out, retval] */ BSTR* something_uri
);
The documentation I have seen on MSDN seems to indicate that you can use parameters with defaultvalue and retval attributes within the same function definition, and I have seen some examples of IDL files that contain such definitions, but I cannot work out how it is possible to write the equivalent C++ definition.
Some clients (and our own test code) use the MIDL generated header files directly, so if I omit the default values from the original C++ header file, the generated function in the MIDL generated file does not contain a default value entry, i.e. it looks like this:
virtual HRESULT STDMETHODCALLTYPE CreateSomething(
/* [in] */ BSTR base_uri,
/* [in] */ ISomethingDescription *something_description,
/* [defaultvalue][out] */ ErrorCode *error_code,
/* [retval][out] */ BSTR *something_uri) = 0;
Similar functions in our SDK include the default values in the IDL file and the C++ header - not to say that that whole approach isn't questionable.
Any help/advice on this would be greatly appreciated.