调用DLL实现DCOM连接后,程序结束正常结束但不能从内存退出,该怎么处理

调用DLL实现DCOM连接后,程序结束正常结束但不能从内存退出
1)编写DLL通过DCOM实现数据存储,查询。主程序采用静态调用方式,函数工作正常,但主程序正常关闭后,主程序不能从内存里退出。
2)DLL里面有多个输出函数需要用到数据模块Tdm_StoredData,频繁调用这个dll是否需要考虑数据模块冲突的问题?
3)DLL调用数据模块中的CDS组件获得查询结果,如何将结果传递到调用主程序,现在使用的是动态数组,有没有更好解决方法?
4)如何实现大块数据在DCOM间传递,那样就可以把这些代码放到DCOM中实现?
C/C++ code

//dll入口
int WINAPI DllEntryPoint(HINSTANCE hinst, unsigned long reason, void* lpReserved)
{
        switch(reason)   
        {
                  case   DLL_PROCESS_ATTACH:
            HRESULT coret = CoInitialize(NULL);   
             if(coret ! = S_OK && coret != S_FALSE)
                        {
                            //异常
                        }
                        else
                        {
                            dm_StoredData =new Tdm_StoredData(NULL);
                        }
                        break;
                  case   DLL_PROCESS_DETACH:
                        if(dm_StoredData !=NULL)
                        {
                                delete dm_StoredData;
                        }
                        CoUninitialize();     
                        break;
                  case DLL_THREAD_ATTACH: break;
                  case DLL_THREAD_DETACH: break;
                  default:
                  break;
}
//变量定义
typedef struct
{
    AnsiString         SID;         
        //....
}SAT, pSAT;
typedef DynamicArray<SAT>  ASAT;

//函数
extern "C" __declspec(dllexport)__stdcall  int Sat_Add(ASAT &asat)
{
    AnsiString CMDSQL;
    int nReturnVal = -1;
    AnsiString satData;
    int x=0;
    CMDSQL = "USE cs select * from work ";
    try
    {
        try{
            dm_StoredData->cds->Active = false;
            dm_StoredData->cds->CommandText = CMDSQL;
            dm_StoredData->cds->Active = true;
            if(dm_StoredData->cds->RecordCount)
            {
                asat.Length = dm_StoredData->cds->RecordCount;
                
                while(!dm_StoredData->cds->Eof)
                {
                    asat[x].SatID = dm_StoredData->cds->FieldByName("id")->AsString;
                    //...
                    x++
                    dm_StoredData->cds->Next();
                }
            }
            dm_StoredData->cds->Active = false;
        }
        catch(Exception &E)
        {
            //ShowMessage(E.Message);
        }
    }
    __finally
    {
        dm_StoredData->cds->Active = false;
    }
    return nReturnVal;
}








------解决方案--------------------
看看下面这代码对楼主有没啥助益(几年前为VB当中做远程调用写的,可能代码看起来会有些许别扭,将就着看吧)
C/C++ code
// EASYDCOMOBJECTIMPL.H : Declaration of the TEasyDCOMObjectImpl

#ifndef EasyDCOMObjectImplH
#define EasyDCOMObjectImplH

#define ATL_APARTMENT_THREADED

#include "EasyDCOMObject_TLB.h"
#include "SConnect.hpp"
#include "MConnect.hpp"


/////////////////////////////////////////////////////////////////////////////
// TEasyDCOMObjectImpl     Implements IEasyDCOMObject, default interface of EasyDCOMObject
// ThreadingModel : Apartment
// Dual Interface : TRUE
// Event Support  : FALSE
// Default ProgID : Project1.EasyDCOMObject
// Description    : 
/////////////////////////////////////////////////////////////////////////////
class ATL_NO_VTABLE TEasyDCOMObjectImpl :
  public CComObjectRootEx<CComSingleThreadModel>,
  public CComCoClass<TEasyDCOMObjectImpl, &CLSID_EasyDCOMObject>,
  public IDispatchImpl<IEasyDCOMObject, &IID_IEasyDCOMObject, &LIBID_EasyDCOMObject>
{
private:
   int Port;
   TInvokeType InvokeType;
   char MethodName;
   char ComputerName[MAX_COMPUTERNAME_LENGTH + 1];
public:
  TSocketConnection *SocketServer;
  TWebConnection *WebServer;
  TDCOMConnection *DCOMServer;
  TEasyDCOMObjectImpl()
  {
     SocketServer=new TSocketConnection(NULL);
     WebServer=new TWebConnection(NULL);
     DCOMServer=new TDCOMConnection(NULL);
     ZeroMemory(ComputerName,MAX_COMPUTERNAME_LENGTH + 1);
     DWORD dNameLen=MAX_COMPUTERNAME_LENGTH + 1;
     GetComputerName(ComputerName,&dNameLen);
     InvokeType=eoiSocketInvoke;
     Port=SocketServer->Port;
  }
  ~TEasyDCOMObjectImpl()
  {
     SocketServer->Free();
     WebServer->Free();
     DCOMServer->Free();
  }
  // Data used when registering Object 
  //
  DECLARE_THREADING_MODEL(otApartment);
  DECLARE_PROGID("EasyDCOMObject.EasyDCOMObject");
  DECLARE_DESCRIPTION("");

  // Function invoked to (un)register object
  //
  static HRESULT WINAPI UpdateRegistry(BOOL bRegister)
  {
    TTypedComServerRegistrarT<TEasyDCOMObjectImpl> 
    regObj(GetObjectCLSID(), GetProgID(), GetDescription());
    return regObj.UpdateRegistry(bRegister);
  }


BEGIN_COM_MAP(TEasyDCOMObjectImpl)
  COM_INTERFACE_ENTRY(IEasyDCOMObject)
  COM_INTERFACE_ENTRY2(IDispatch, IEasyDCOMObject)
END_COM_MAP()

// IEasyDCOMObject
public:
 
  STDMETHOD(GetName(BSTR* S));
  STDMETHOD(set_Port(const int Value));
  STDMETHOD(get_Port(int* Value));
  STDMETHOD(set_InvokeType(const TInvokeType Value));
  STDMETHOD(get_InvokeType(TInvokeType* Value));
  STDMETHOD(GetObj(const BSTR PROGID,const BSTR SERVER,IDispatch ** iObj));
};

#endif //EasyDCOMObjectImplH