最近学习COM的编程,开发工具是VC6.0的ATL。
用两个线程进行测试,主线程(Main Thread)和一个新开的线程(New Thread)。两个线程实例化的同一个COM组件。
主要测试的是COM的套间,套间主要是规范对象和线程之间的关系,不在同一个套间的线程和对象,线程不能直接访问。
以下是各种情况下的测试。
一:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)
New Thread:CoInitialize(NULL)
对象线程模型:Single
Main Thread ID:4156
Object Pointer:1447804
COM OBJECT's THreadID:2880
New Thread ID:5920
Object Pointer:18897832
COM OBJECT's THreadID:5920
二:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)
New Thread:CoInitialize(NULL)
对象线程模型:Apartment
Main Thread ID:2288
Object Pointer:1447804
COM OBJECT's THreadID:5316
New Thread ID:2496
Object Pointer:18897832
COM OBJECT's THreadID:2496
三:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)
New Thread:CoInitialize(NULL)
对象线程模型:Free
Main Thread ID:4912
Object Pointer:4152232
COM OBJECT's THreadID:4912
New Thread ID:5396
Object Pointer:1437828
COM OBJECT's THreadID:5400
四:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)
New Thread:CoInitialize(NULL)
对象线程模型:Both
Main Thread ID:4964
Object Pointer:4152232
COM OBJECT's THreadID:4964
New Thread ID:5920
Object Pointer:11230120
COM OBJECT's THreadID:5920
五:Main Thread:CoInitialize(NULL)
New Thread:CoInitialize(NULL)
对象线程模型:Apartment
Main Thread ID:5364
Object Pointer:10181544
COM OBJECT's THreadID:5364
New Thread ID:5368
Object Pointer:11230120
COM OBJECT's THreadID:5368
六:Main Thread:CoInitialize(NULL)
New Thread:CoInitialize(NULL)
对象线程模型:Single
Main Thread ID:5884
Object Pointer:10181544
COM OBJECT's THreadID:5884
New Thread ID:1752
Object Pointer:11230120
COM OBJECT's THreadID:1752
七:Main Thread:CoInitialize(NULL)
New Thread:CoInitialize(NULL)
对象线程模型:Free
Main Thread ID:5068
Object Pointer:1437380
COM OBJECT's THreadID:5580
New Thread ID:4528
Object Pointer:1425180
COM OBJECT's THreadID:5992
八:Main Thread:CoInitialize(NULL)
New Thread:CoInitialize(NULL)
对象线程模型:Both
Main Thread ID:4216
Object Pointer:10181544
COM OBJECT's THreadID:4216
New Thread ID:1524
Object Pointer:11230120
COM OBJECT's THreadID:1524
九:Main Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)
New Thread:CoInitializeEx(NULL,COINIT_MULTITHREADED)
对象线程模型:Free
Main Thread ID:5960
Object Pointer:4152232
COM OBJECT's THreadID:5960
New Thread ID:5212
Object Pointer:4152232
COM OBJECT's THreadID:5212
只有第九种情况的时候,两个线程访问的是同一个对象。
为了了解不同情况下的对象调用步骤,这两天使用windbg,对调用过程进行了单步跟踪(跨线程的调用过程太麻烦了,没有跟踪完
,呵呵,只是看到RPC调用的处理),所以以下的结论是的的确确的哦。
套间分为STA和MTA两种,COM组件的线程模型由single、apartment、free、both四种指定(测试没有发现single和apartment的区别,难道是遗留分类,后来已经一样了),STA包括single、apartment、both ,MTA包括free、both,和对象相同套间类型线程才能够直接加载对象,否则需要通过RPC跨线程进行访问,参数也需要进行特殊处理(marshal)才能够传递。
需要特殊处理的是多个Free线程加载Free对象,这时这些个Free线程访问的是同一个Free对象,需要进行同步处理。
以上是我这两天的成果,针对的是进程内COM对象调用,下一步研究跨进程调用。