COM+预研总结(4)

来源:互联网 发布:软件开发工程师课程 编辑:程序博客网 时间:2024/05/16 18:51

(1)定义COM对象为单一实例。
DECLARE_CLASSFACTORY_SINGLETON(CPatient),
DECLARE_CLASSFACTORY_SINGLETON宏定义COM对象为单一实例。
在配置COM+对象属性激活上下文中的属性有关(不要选中组件支持事件和数据统计)


(2)COM对象线程模型为Both,支持COM+服务器多线程访问该对象,注意对象的成员对象的线程安全性。

 

(3)创建工程时合并PROXY/STUB。

 

(4)COM对象中每启动新线程要初始化COM套件
 ::CoInitializeEx( NULL, COINIT_MULTITHREADED );
启动多线程套间。这样事件通知等就不用边界调整。一个进程中最多只有一个多线程套件,所以所有进入多线程套件的线程其实都在一个套件当中,互相访问不用条件调整。

 

(5)由于要配置成COM+服务,所以必须考虑到跨边界访问问题。
所有事件接口都直接继承IUnknown接口,因为我们肯定只用VC++访问,不需要定义成IDispatch接口。
为了开发方便,是否跨边界要透明。所以接口要支持结构体、指针、数组等。
跨边界调整要通过默认调整规则。
接口定义如下:
HRESULT OnGetAllAlarmBrief([in] LONG lPatientiID, [in,size_is(lCount),unique] struct STUAlarmBrief * pstuAlarmBrief, [in] LONG lCount,。。。);

size_is(lCount)属性定义调整pstuAlarmBrief数组有多长。
unique属性定义pstuAlarmBrief为指针,并且可以为空(ref属性是不可以为空的)(unique、ref、ptr区别参考MSDN)。

接口中参数若为结构体,并且结构体中含有指针,要像面定义
struct STU_STREVIEW_DATA_INFO_SHORTTREND
{
    。。。
      [unique, size_is(lTrenddataCount)]struct STUParamShortTrend *parrTrendInfo;   

      long lTrenddataCount;     
      。。。
};

//若不是数组,可以不用size_is(lTrenddataCount)属性,规则和上述结构说明相同

 

(6)内存管理问题:
[in]属性是谁调用谁释放,[out]属性是谁调用谁释放,但调用端要事先分配好内存。
尽量不要使用[retval]属性,特别是参数是复杂结构体时(例如结构体变量中有VARIANT类型时,可能引发不可预知的问题)。
 
(7)要注意VARIANT类型,一定要先初始化(VariantInit),用过后释放(VariantClear)。否则可能出现异常(没有调用VariantInit的参数),或内存泄露(没有VariantClear)。


通过这些学习到了分布式编程的思想,COM确实很复杂,不过功能还是很强大的,很多东西了解了机制,可以根据实际需要修改,提升方便性和性能。可以实现不改动代码只通过配置就可以实现单机版和服务器版软件。很可惜,没有见到最终的成果。

原创粉丝点击