2011-08-18 11 views
3

C++ 프로그램에서 IWebBrowser2 컨트롤을 호스팅하고 있는데, 보통 Win32 (mfc, atl, wtl 등 없음)를 사용합니다. DISPID_NAVIGATECOMPLETE2에서 표시된 웹 페이지에서 실행중인 javascript에서 액세스 할 사용자 정의 객체를 추가합니다.내 IDispatch 개체에 대한 모든 참조가 해제되지 않는 이유는 무엇입니까?

사용자 지정 개체를 추가하려면 DISPATCH_PROPERTYPUT을 사용하여 InvokeEx를 호출하고 사용자 지정 개체를 가리키는 DISPPARAMS 구조체를 호출합니다.

InvokeEx를 호출하는 동안 내 사용자 지정 개체의 AddRef 함수가 호출되고 참조 카운터가 증가합니다. 그러나 객체는 Release 함수를 호출하지 않으므로 참조 카운터는 결코 0으로 다시 감소하지 않습니다.

InvokeEx에서 AddRef()를 호출 한 후 누가 Release()를 호출해야합니까?

편집 :

(일부 코드를 추가) 이것은 IHTMLWindow2 내 사용자 지정 개체를 추가하는 코드입니다. 이제

: 이것은 추가 해요 객체가

IHTMLWindow2 *win = NULL; 
GetDoc()->get_parentWindow(&win); 
IDispatchEx *winEx = NULL; 
win->QueryInterface(&winEx); 

DISPID dispid; 
HRESULT hr = winEx->GetDispID(objName, fdexNameEnsure, &dispid); //objName is "JSObject" 

DISPID namedArgs[] = {DISPID_PROPERTYPUT}; 
DISPPARAMS params; 
params.rgvarg = new VARIANT[1]; 
params.rgvarg[0].pdispVal = custObj; 
params.rgvarg[0].vt = VT_DISPATCH; 
params.rgdispidNamedArgs = namedArgs; 
params.cArgs = 1; 
params.cNamedArgs = 1; 

hr = winEx->InvokeEx(dispid, LOCALE_USER_DEFAULT, DISPATCH_PROPERTYPUT, &params, NULL, NULL, NULL); 

내 사용자 정의 개체에 대한 custObj 포인트

class JSObject : public IDispatch { 
private: 
    long ref; 
public: 
    JSObject(); 

    // IUnknown 
    virtual HRESULT STDMETHODCALLTYPE QueryInterface(REFIID riid, void **ppv); 
    virtual ULONG STDMETHODCALLTYPE AddRef(); 
    virtual ULONG STDMETHODCALLTYPE Release(); 

    // IDispatch 
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfoCount(UINT *pctinfo); 
    virtual HRESULT STDMETHODCALLTYPE GetTypeInfo(UINT iTInfo, LCID lcid, 
     ITypeInfo **ppTInfo); 
    virtual HRESULT STDMETHODCALLTYPE GetIDsOfNames(REFIID riid, 
     LPOLESTR *rgszNames, UINT cNames, LCID lcid, DISPID *rgDispId); 
    virtual HRESULT STDMETHODCALLTYPE Invoke(DISPID dispIdMember, REFIID riid, 
     LCID lcid, WORD wFlags, DISPPARAMS *pDispParams, VARIANT *pVarResult, 
     EXCEPINFO *pExcepInfo, UINT *puArgErr); 
}; 

편집 2 (일부 민간 위원은 간결 탈락 한) 내가 github에 그것을두기로 ​​결정해야하는 것처럼 그것은 일하고있는 것처럼 보인다.

https://github.com/Tobbe/CppIEEmbed. 당신이 할 수있는 경우 포크하고 향상하십시오 :)

+0

할당 한 속성을 정확하게 문서화하십시오. 개체를 할당하기 때문에 DISPATCH_PROPERTYPUTREF btw 여야합니다. –

+0

DISPATCH_PROPERTYPUTREF를 사용하는 경우 InvokeEx가 DISP_E_MEMBERNOTFOUND와 함께 실패합니다. – Tobbe

+0

@ 한스 패 탄트 : "어떤 속성을 할당했는지 정확하게 문서화"라고 말하면 무엇을 요구하는지 잘 모르겠습니다. 내 질문에 추가 한 코드가 귀하가 요구 한 것을 제공합니까? – Tobbe

답변

2

글쎄, 당신은 속성을 할당하고 있습니까? 이 속성이 존재하고 개체를 참조하는 한 참조가 추가됩니다.

원격 개체에서 참조를 해제하려면 속성이나 다른 개체에 NULL을 할당해야합니다.

+0

나는이 질문에 명시된 있어야하지만 중요한 것은 "원격 개체"가 파괴 될 때 내 참조가 해제되지 않습니다. 죽기 전에 할당 된 모든 속성을 해제해야합니까? – Tobbe

+0

나는해야한다. 그러나 당신은 원격 객체가 정말로 파괴되었는지, 그리고 다른 참조가 주위에 매달려 있지 않은지 확신합니까? – rodrigo

+0

원격 객체를 올바르게 릴리스하지 않아서 결코 파괴되지 않았습니다. 그리고 파괴 된 이후로 내 사용자 정의 객체 (내 JSObject 인스턴스)에 대한 참조가 유지되었습니다. – Tobbe