by jasper » 24 March 2022, 11:54
1,2) A BSTR value is a pointer (a wchar_t*, to be precise), the value of which is either NULL, or something allocated by SysAllocString or similar functions, and needs to be released by SysFreeString. As the string is passed between applications, it is rather important that not both applications free the same string, so you are responsble for freeing and allocating the correct strings. In general, if COM arguments are marked as [in] you should not free the string (hence you should make a copy at put_value), if arguments are marked as [out] you allocate it but the other side releases it (hence again a copy is needed). If you have two internal variables of the BSTR type your class destructor should release the non-zero values. Hence they should probably not point to the same thing. Many applications use BSTR wrappers, similar to smart pointers, to keep track of this.
3) res.vt=VT_BSTR,
res.bstrVal=SysAllocStringLen(someWstr.c_str(),someWstr.size()) , or res.bstrVal=SysAllocString(someWstr.c_str())
note that the above is only correct for non-empty strings. Empty BSTRs should be nullptr/NULL.
4) making an option list generally causes a GUI to provide a drop down box with options, which is ok for input values. Output values typically do not have such a list of options. You can return an empty VARIANT (vt=VT_EMPTY) or a string array (vt=VT_ARRAY|VT_BSTR) - in the latter case you should put a SAFEARRAY in the parray member, the SAFEARRAY should be 1 dimensional, starting at index 0, and have BSTR members. All of this is allocated by your function, and released by the caller.
5) as the parameter cannot be directly created by the outside world, its CLSID does not matter, and you do not need an OBJECT_ENTRY_AUTO at all.