none
CLR Interop, BSTR and COM RRS feed

  • Question

  • I have a question about a potential memory leak :-

    I have a C++/COM server running out-of-proc and a C# client connected through COM interop. From C++ I used to fire event as

    sipxEvent.InvokeHelper(0x1,
                                            DISPATCH_METHOD,
                                            VT_EMPTY,
                                            NULL,
                                            paramInfo, //param info types: VTS_...
                                            hCall,
                                            hLine,
                                            event,
                                            cause,
                                            _ConvertStringToBSTR (pszRemoteParty),
                                            lpdispCallInfo);

    This basically fire following event declared in IDL,

    [ uuid(FA1A568E-EC16-4af4-8C7F-BD448057622F) ]
        dispinterface _ISipEventCallback
        {

                [
                    id(1),
                    helpstring("method OnCallEvent")
                ]
                HRESULT OnCallEvent(ccc_call_id iCallId,
                                    ccc_line hLine,
                                    sip_callstate_event event,
                                    sip_callstate_cause cause,
                                    BSTR bstrRemoteParty,
                                    IDispatch* info);

        ...

     }

    And the corresponding C# interop. is as below,

    [ComImport, TypeLibType((short) 0x1000), InterfaceType((short) 2), Guid("FA1A568E-EC16-4AF4-8C7F-BD448057622F")]
    public interface _ISipEventCallback
    {
        [MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(1)]
        void OnCallEvent(int iCallId,
                                    int hLine,
                                    sip_callstate_event @event,
                                    sip_callstate_cause cause,
                                    [MarshalAs(UnmanagedType.BStr)] string bstrRemoteParty,
                                    [MarshalAs(UnmanagedType.IDispatch)] object info);
       
    }

     Now at the time of firing events, I used to call _ConvertStringToBSTR (pszRemoteParty) which allocates a new BSTR (in server process) and then fire to CLR [ (marshalled to client pocess - COM marshaler) and then marshalled to CLR (CLR marshaler) ]. Ideally a copy of BSTR exists in both client and server. They say that 'CLR frees automatically the BSTR by a equivalent call to ::SysFreeString(bstr)'. Is that right? If I don't free it explicitly in server, is there a memory leak?

    I know this is more related to C++, so I posted there as well.

    -Thanks
    Deb.

     

                          
    Saturday, August 2, 2008 7:38 AM

All replies

  • It's correct that the CLR will do the right thing and free its copy of the string on the client side. But since it's an input parameter, you are responsible for freeing the BSTR you allocate on the server side.

    Mattias, C# MVP
    Wednesday, August 13, 2008 8:06 AM
    Moderator