调用DLL实现DCOM连接后,程序结束正常结束但不能从内存退出
1)编写DLL通过DCOM实现数据存储,查询。主程序采用静态调用方式,函数工作正常,但主程序正常关闭后,主程序不能从内存里退出。
2)DLL里面有多个输出函数需要用到数据模块Tdm_StoredData,频繁调用这个dll是否需要考虑数据模块冲突的问题?
3)DLL调用数据模块中的CDS组件获得查询结果,如何将结果传递到调用主程序,现在使用的是动态数组,有没有更好解决方法?
4)如何实现大块数据在DCOM间传递,那样就可以把这些代码放到DCOM中实现?
//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;}
// 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()// IEasyDCOMObjectpublic: 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
[解决办法]
由于水平有限.楼主的问题出在哪我不知道.
但总感觉有些得不偿失.
即然用到了RDM. 为什么还要按普通的DLL的方式来写代码.
2)DLL里面有多个输出函数需要用到数据模块Tdm_StoredData,频繁调用这个dll是否需要考虑数据模块冲突的问题?
为什么不用TDCOMConnection. TSocketConnection ...的AppServer接口.还要自己导出一堆函数.
3)DLL调用数据模块中的CDS组件获得查询结果,如何将结果传递到调用主程序,现在使用的是动态数组,有没有更好解决方法?
RDM上的TDataSetProvider的DataSet属性指向ADOQuery/ADOxxxx. 当ADOQurery/ADOxxxx打开的时候. 直接返回TDatasetProvider的Data属性就行了.
4)如何实现大块数据在DCOM间传递,那样就可以把这些代码放到DCOM中实现?
大块有多大, 如果在同一台机器上. 一般情况下不切成小块也可以. 先试试看为好.