為了實驗,寫了一個COM組件嵌入HTML,大概功能是接收服務(wù)器的數(shù)據(jù),并顯示出來
HTML 調(diào)用COM組件的代碼大概是這樣的:
<html>
<SCRIPT LANGUAGE="JavaScript">
<!--?
?function onRecvData()
?{
?????? try
?????? {
?????????? var obj_Connection = new ActiveXObject("MyObj.MyObj.1");
?????????? obj_Connection.OnRecv = function onRecv(buf, len)
????????? {
????????????? testbox.value = buf;
??????????} ;
?????????? obj_Connection.init(12345);?
??????? }
??????? catch(e)
??????? {
?????????? var strErrMsg;
?????????? strErrMsg = "Error: " + e.message;
?????????? alert(strErrMsg);
??????? }
??? }
//-->
</SCRIPT>
</HEAD>
<BODY>
<input onClick="onRecvData();" type="button" value="Go">
<input type="text" id = testbox>
</BODY>
</html>
COM組件在接收到SOCKET的數(shù)據(jù)之后,就會調(diào)用
void CMyObj::onReceive(const char* pData, int nLen)
{
?if ( m_pfnRecv != NULL )
?{
??CComVariant* pvars = new CComVariant[2];
???
??pvars[1] = pData;
??pvars[0] = nLen;?
??
??DISPPARAMS disp = { pvars, NULL, 2, 0 };
??HRESULT hr = m_pfnRecv->Invoke(0, IID_NULL, LOCALE_USER_DEFAULT, DISPATCH_METHOD, &disp, NULL, NULL, NULL);
??delete[] pvars;
??
?}// if ( m_pfnRecv != NULL )
}
其中的 m_pfnRecv 就是通過 STDMETHODIMP CMyObj::put_OnRecv(IDispatch *newVal) 的方法設(shè)置進(jìn)去的
發(fā)現(xiàn)在調(diào)用幾十次(大約80次左右后),COM組件會出錯(訪問的地址不可讀),出錯堆棧大約如下:
First-chance exception in IEXPLORE.EXE (JSCRIPT.DLL): 0xC0000005: Access Violation.
JSCRIPT! 75bc4a27()
JSCRIPT! 75bc7564()
JSCRIPT! 75bc7414()
JSCRIPT! 75bc678e()
CMyObj::onReceive(const char * 0x0012e40c, int 260) line 64 + 44 bytes
想了很久,沒想出好的解決方法,一直在懷疑是否是 m_pfnRecv->Invoke 調(diào)用的問題
于是乎做了以下的實驗:
將HTML調(diào)用COM組件的代碼改為:
<html>
<SCRIPT LANGUAGE="JavaScript">
<!--?
function onRecv(buf, len)
{
?????? testbox.value = buf;
} ;
?function onRecvData()
?{
?????? try
?????? {
?????????? var obj_Connection = new ActiveXObject("MyObj.MyObj.1");
?????????? obj_Connection.OnRecv =?onRecv;
?????????? obj_Connection.init(12345);?
??????? }
??????? catch(e)
??????? {
?????????? var strErrMsg;
?????????? strErrMsg = "Error: " + e.message;
?????????? alert(strErrMsg);
??????? }
??? }
//-->
</SCRIPT>
</HEAD>
<BODY>
<input onClick="onRecvData();" type="button" value="Go">
<input type="text" id = testbox>
</BODY>
</html>
改完之后,又發(fā)現(xiàn)另一問題
在調(diào)用幾十次之后,它會走到 CMyObj 的析構(gòu)
?~CMyObj()
?{
?}
每次點擊 Go 按鈕, 它都會執(zhí)行幾十次后,就析構(gòu)
于是乎,再改了下HTML ,將 obj_Connection 改為全局變量
<html>
<SCRIPT LANGUAGE="JavaScript">
<!--?
var var obj_Connection;
function onRecv(buf, len)
{
?????? testbox.value = buf;
} ;
?function onRecvData()
?{
?????? try
?????? {?
???????????obj_Connection = new ActiveXObject("MyObj.MyObj.1");
?????????? obj_Connection.OnRecv =?onRecv;
?????????? obj_Connection.init(12345);?
??????? }
??????? catch(e)
??????? {
?????????? var strErrMsg;
?????????? strErrMsg = "Error: " + e.message;
?????????? alert(strErrMsg);
??????? }
??? }
//-->
</SCRIPT>
</HEAD>
<BODY>
<input onClick="onRecvData();" type="button" value="Go">
<input type="text" id = testbox>
</BODY>
</html>
這下終于正常了,只有每當(dāng)按 F5去刷新頁面的時候,才會調(diào)用到 MyObj 的析構(gòu)
需要再細(xì)究下原因。