COM 初始化

COM 初始化,说简单很简单,说复杂,有些时候还真不简单。

首先,CoInitialize(NULL)和CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);是一样的。我们尽可能使用CoInitializeEx来初始化COM比较好。

STA套间

调用CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);,那么COM系统就会为calling thread创建一个单线程套间。

如果再调用一次CoInitializeEx(NULL, COINIT_APARTMENTTHREADED);那么CoInitializeEx()还是会成功,但是返回一个S_FALSE。也就是说多次初始化COM是可以的。

但是如果在初始化成单线程套间后,再去尝试初始化多线程套间,那就会失败,返回值会提示“不可以修改套间类型”啥的。

每一次成功的CoInitializeEx都最后有一个对应的CoUninitialize(),这样就比较优雅。当然如果不CoUninitialize,通常问题也不大。

一个进程里面可以有多个STA套间,每个STA套间有且仅有一个线程。一个STA套间里面可以有多个STA对象。

MTA套间

使用CoInitializeEx(NULL, COINIT_MULTITHREADED);来创建一个MTA套间。一个进程里面只能有一个MTA套间。

比如我们在主线程里面创建了MTA套间,那么主线程就属于MTA套间。所有其他辅助线程,如果自己没有初始化COM,那么默认就属于MTA套间。

如果辅助线程自己初始化COM,就看情况而定。总体来说,当主线程初始化成MTA后,辅助线程有三种情况:

1. 辅助线程不初始化COM,那么就默认属于MTA套间

2. 辅助线程初始化成MTA套间,那么还是属于MTA套间

3. 辅助线程初始化成STA套间,那么辅助线程就属于STA套间。

一个进程只有1个MTA套间,但是可以有多个STA套间。每个MTA套间里面可以有多个线程。



时间: 2024-11-04 09:49:12

COM 初始化的相关文章

Java的成员变量初始化

对于方法里面的成员变量,Java要求程序员强制提供一个初始化的值.比如下面这个方法就会出错: public class Breakyizhan{ public void Z(){ int z; z++; } public static void main(String[] args) { Breakyizhan B = new Breakyizhan(); B.Z(); } } /* (www.breakyizhan.com) 输出结果是: 编译会出错,方法变量没有初始化 */ 而对于类的数据,

快学Scala 第二十一课 (初始化trait的抽象字段)

初始化trait的抽象字段: trait Logged { println("Logged constructor") def log(msg: String){ println("Logged")} } trait FileLogger extends Logged { var filename: String override def log(msg: String) { println("filename:" + filename) } }

main.c 流程-buffer初始化

void buffer_init(long buffer_end)函数的理解: *   0         0x100000          0x400000                    0x10 00000(16M) *    ---------------------------------------------------------- *   |   kernel  | memery buffer   |   main memory              |      

AS3 Vecter初始化

var vec : Vecter.<Point> = new <Point>[     new Point(1,1),     new Point(1,2) ]; 类似于 Array的初始化的方法. var arr : Array = [1,2]; 当然Vecter的常规初始化: var vec : Vecter.<Point> = new Vecter.<Point>();//这样的话要赋值的话需要使用push等函数. 注意要: ① new <Poi

对象初始化

对象初始化过程 第一步:在创建之前,检查是否加载(检查硬盘上的class文件是否加载到内存中,如果没有加载,就先加载父类的文件) 在加载父类的文件,在加载本类的文件中java使用的加载的策略:懒惰式加载(按需加载)用到的时候,只加载一次. 第二步:分配对象的空间.递归分配所有父类和子类的属性空间,属性会自动初始化为"0"的值 第三步:给属性赋值 第四步:调用父类的构造方法(默认调用父类的无参构造方法) 第五步:调用本类的构造方法

s5pv210——初始化SDRAM

1:SDRAM基础: 通过s3c2440的内存原理以及时序来理解s5pv210 SDRAM原理.时序. 首先看一下核心板内存如何连接的 可以看一下两个内存芯片接的地址总线均为Xm1_ADDR[13:0],数据总线Xm1_DATA[15:0].Xm1_DATA[31:16],两个内存芯片是并联的,当地址总线Xm1_ADDR[13:0]寻址时, 可以同时在两个内存芯片上各获取16位数据来组成一个32位数据,并由32位数据总线输出. 在看下面这幅图:下图为每个内存芯片内部框图:Block Diagra

安装初始化mysql后,默认几个库介绍

背景介绍:  当我们安装初始化mysql后,默认建了几个数据库,那么这些数据库有什么作用呢?mysql> show databases;+--------------------+| Database           |+--------------------+| information_schema || mysql              || performance_schema || test               |+--------------------+4 rows

Linux C中结构体初始化

    在阅读GNU/Linux内核代码时,我们会遇到一种特殊的结构初始化方式.该方式是某些C教材(如谭二版.K&R二版)中没有介绍过的.这种方式称为指定初始化(designated initializer).下面我们看一个例子,Linux-2.6.x/drivers/usb/storage/usb.c中有这样一个结构体初始化项目: static struct usb_driver usb_storage_driver = { .owner = THIS_MODULE, .name = "

基于verilog的SDRAM初始化

目录 1.SDRAM初始化的内容(结合英文数据手册) 2.SDRAM初始化的时序 3.代码的编写 4.modesim的仿真 SDRAM初始化的内容 SDRAMs must be powered up and initialized in a predefined manner. The 64M SDRAM is initialized after the power is applied to Vdd and Vddq, and the clock is stable with DQM High

初始化和类装载

由于 Java 中的一切东西都是对象,所以许多活动变得更加简单,这个问题便是其中的一例.Java中每个对象的代码都存在于独立的文件中.除非真的需要代码,否则那个文件是不会载入的.通常,我们可认为除非那个类的一个对象构造完毕,否则代码不会真的载入.装载的时候,所有static对象和 static代码块都会按照本来的顺序初始化(亦即它们在类定义代码里写入的顺序).当然,static 数据只会初始化一次. 1.继承初始化 我们有必要对整个初始化过程有所认识,其中包括继承,对这个过程中发生的事情有一个整