哪个公寓是班级对象?

时间:2014-09-07 04:53:08

标签: winapi com

假设我们有一个进程内服务器。客户端线程在MTA中,但该对象不是自由线程的(即存在于STA中)。

CoGetClassObject是在MTA中还是在新STA中创建类对象?

类对象是否总是在类对象所在的同一个公寓中创建对象,还是可以在其他公寓中创建它们?

1 个答案:

答案 0 :(得分:4)

因此,您的COM服务器是标记为“公寓”线程的进程内COM类,您将从MTA线程实例化它。

您的CoGetClassObject(或CoCreateInstance)电话会执行以下操作:

  • 使用传递的CLSID,COM检测到服务器需要STA,呼叫者是MTA
  • 如果需要,可以创建STA,即如果进程没有使用STA,则COM创建工作线程
  • COM根据需要加载服务器DLL并在STA线程上调用DllGetClassObject
  • COM为获得的类工厂创建代理/存根对,并将控制权传递回调用者线程
  • MTA呼叫者接收IClassFactory*接口指针,指向代理而不是真正的工厂;代理在其MTA端接受调用以将它们传输到服务器的本地STA
  • 在MTA线程上收到进一步的客户端调用,并在内部传递给STA线程,在那里进行真正的类工厂调用,然后发生真正的实例化(marhsaling)

COM将尽力将所有[合法]呼叫转移到上述STA。如果你想办法愚弄它,例如您可以在MTA代码中获得指向类工厂的直接指针(通过GetModuleHandleGetProcAddressDllGetClassObject或者在STA上获取指针,然后将其传递给MTA而不进行编组),它将在即使可能有一些意想不到的行为开始。在以后/当您通过代理拨打电话时,您将收到RPC_E_WRONG_THREAD错误。也就是说,您通常有兴趣遵守COM规则,即使有时它们的违规行为不会立即导致失败。