多次调用编组的 COM 接口
Invoke marshalled COM interface multiple times
我正在编写一个 COM 对象供 JavaScript 使用。 JavaScript 代码依次在托管的 WebBrowserControl 中运行。我需要从 COM 对象触发一些事件到 JavaScript,这是 Dr. Dobbs
的优秀指南
例如
我的 *.idl
中有以下内容
IJSCallback
{
void Listen(IDispatch* pJSMethod);
}
JavaScript 方法在 C++ 代码中作为 IDispatch*
接收,将被存储以供稍后从另一个线程调用它。
无论使用何种编组方法(CoMarshalInterThreadInterfaceInStream
或 IGlobalInterfaceTable
),事件触发线程只能调用一次 JavaScript 函数。之后 IDispatch::Invoke()
returns E_ACCESSDENIED
!
样本JavaScript代码
var server = new ActiveXObject("prog_id")
var.Listen(function(ip_add) {
// ip_add from COM object
});
C++ 线程非常简单。
// called from JavaScript
CMyObject::Listen(IDispatch* pJSMethod)
{
// IStream* m_pStream;
CoMarshalInterThreadInterfaceInStream(pJSMethod, IID_IDispatch, &m_pStream);
}
// called from internal C++ thread.
CMyObject::FireEvent()
{
// IStream* m_pStream;
// IDispatch* m_pJSMethod;
CoGetInterfaceAndReleaseStream(m_pStream, IID_IDispatch, (LPVOID*)&m_pJSMethod);
HSREULT hr = m_pJSMethod->Invoke(...); // hr = S_OK, call is received in JavaScript
hr = m_pJSMethod->Invoke(...); // hr = E_ACCESSDENIED, call is not received in JavaScript
}
这是预期的行为吗?还是代码有问题?
已修复。如评论中所述,alert()
有效,但 document.writeln()
无效。那是因为document.writeln()
重置了当前包含scripts元素的文档,使用document.createElement()
、document.createTextNode()
和朋友修改当前加载的元素。
对于熟悉 HTML/JavaScript 的人来说,这可能是常识,对于我们其他人来说,这可能是一个真正的交易。
我正在编写一个 COM 对象供 JavaScript 使用。 JavaScript 代码依次在托管的 WebBrowserControl 中运行。我需要从 COM 对象触发一些事件到 JavaScript,这是 Dr. Dobbs
的优秀指南例如 我的 *.idl
中有以下内容IJSCallback
{
void Listen(IDispatch* pJSMethod);
}
JavaScript 方法在 C++ 代码中作为 IDispatch*
接收,将被存储以供稍后从另一个线程调用它。
无论使用何种编组方法(CoMarshalInterThreadInterfaceInStream
或 IGlobalInterfaceTable
),事件触发线程只能调用一次 JavaScript 函数。之后 IDispatch::Invoke()
returns E_ACCESSDENIED
!
样本JavaScript代码
var server = new ActiveXObject("prog_id")
var.Listen(function(ip_add) {
// ip_add from COM object
});
C++ 线程非常简单。
// called from JavaScript
CMyObject::Listen(IDispatch* pJSMethod)
{
// IStream* m_pStream;
CoMarshalInterThreadInterfaceInStream(pJSMethod, IID_IDispatch, &m_pStream);
}
// called from internal C++ thread.
CMyObject::FireEvent()
{
// IStream* m_pStream;
// IDispatch* m_pJSMethod;
CoGetInterfaceAndReleaseStream(m_pStream, IID_IDispatch, (LPVOID*)&m_pJSMethod);
HSREULT hr = m_pJSMethod->Invoke(...); // hr = S_OK, call is received in JavaScript
hr = m_pJSMethod->Invoke(...); // hr = E_ACCESSDENIED, call is not received in JavaScript
}
这是预期的行为吗?还是代码有问题?
已修复。如评论中所述,alert()
有效,但 document.writeln()
无效。那是因为document.writeln()
重置了当前包含scripts元素的文档,使用document.createElement()
、document.createTextNode()
和朋友修改当前加载的元素。
对于熟悉 HTML/JavaScript 的人来说,这可能是常识,对于我们其他人来说,这可能是一个真正的交易。