I have a class (JSObject) that implements the IDispatch interface. The class is exposed to JavaScript running in my hosted web browser control (IWebBrowser2).
See more here about how this works: http://stackoverflow.com/questions/3747414/calling-c-function-from-javascript-script-running-in-a-web-browser-control
I can call in to JSObject from my JavaScript code, and I can receive returned integers/longs. But something goes wrong when the function returns a string (BSTR).
This is a part of the IDispatch::Invoke()
code:
int lenW = MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, "Returned string", -1,
NULL, 0);
BSTR bstrRet = SysAllocStringLen(0, lenW);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, "Returned string", -1, bstrRet,
lenW);
pVarResult->vt = VT_BSTR;
pVarResult->bstrVal = bstrRet;
// Who calls SysFreeString(bstrRet);?
With the above code you can alert()
the returned string, but you can not add to it. alert(returnedString + "foo");
will only show "Returned string". The "foo" part is not added to the string. There seems to be something wrong with the end of the string somehow. Any ideas anyone?
Also, am I leaking memory here since I'm not calling SysFreeString()
?
EDIT:
I temporarily included atlbase.h so I could use CComBSTR
. The above code now looks like this:
pVarResult->vt = VT_BSTR;
pVarResult->bstrVal = CComBSTR("test string");
Stepping through that code definitely shows that pVarResult is "test string" all the way until the function returns. But when I alert() the returned string in my JavaScript code I get "expanded". alert(returnedString + "foo")
is "expandedfoo". So it is a small step in the right direction as you can add to the returned string. But it's also a step in the wrong direction as the returned string isn't what I really returned...
*pVarResult = CComVariant("test string");
That code gives the same results as the code in the previous listing (using CComBSTR).