【发布时间】:2011-04-14 19:59:35
【问题描述】:
我有一个实现 IDispatch 接口的类 (JSObject)。该类暴露给在我的托管 Web 浏览器控件 (IWebBrowser2) 中运行的 JavaScript。
在此处查看有关其工作原理的更多信息:Calling C++ function from JavaScript script running in a web browser control
我可以从我的 JavaScript 代码中调用 JSObject,并且我可以接收返回的整数/长整数。但是当函数返回一个字符串(BSTR)时出现了问题。
这是IDispatch::Invoke()代码的一部分:
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);?
使用上面的代码你可以alert()返回的字符串,但是你不能添加它。 alert(returnedString + "foo"); 只会显示“返回的字符串”。 “foo”部分不会添加到字符串中。不知何故,字符串的结尾似乎有问题。有什么想法吗?
另外,因为我没有打电话给SysFreeString(),所以我会在这里泄漏内存吗?
编辑:
我暂时包含了 atlbase.h,所以我可以使用 CComBSTR。上面的代码现在看起来像这样:
pVarResult->vt = VT_BSTR;
pVarResult->bstrVal = CComBSTR("test string");
单步执行该代码肯定表明 pVarResult 一直是“测试字符串”,直到函数返回。但是当我在我的 JavaScript 代码中 alert() 返回的字符串时,我得到了“扩展”。 alert(returnedString + "foo") 是“扩展的foo”。所以这是朝着正确方向迈出的一小步,因为您可以添加到返回的字符串中。但这也是朝着错误方向迈出的一步,因为返回的字符串不是我真正返回的......
*pVarResult = CComVariant("test string");
该代码给出的结果与前面列表中的代码相同(使用 CComBSTR)。
【问题讨论】:
-
我没有看到它(用于 ATL),但仅供参考:输出参数归调用者所有,因此调用者释放了字符串。请参阅memory management rules here。
-
@Georg:太好了。所以至少我没有泄漏内存。
标签: javascript c++ windows com iwebbrowser2