La creación de un proyecto ATL en MSVC parece crear no uno sino dos proyectos; este último llamó igual que el anterior pero con PS anexado a su nombre. ¿Cuál es el propósito de este segundo proyecto y cómo puedo saber si lo necesito?
Respuesta
COM soporta método de toma de interfaz de llamadas a través de dos hilos diferentes, dos procesos diferentes o dos máquinas diferentes. Esto se llama calcular referencias. Dos subprocesos diferentes es el caso más común, un servidor COM a menudo no es seguro para subprocesos. COM implementa seguridad de subprocesos para tales coflasses de un solo subproceso al ordenar la llamada del subproceso 'incorrecto' al subproceso que creó el servidor. El mapeo entre procesos ocurre cuando se escribe un servidor fuera de proceso. Entre diferentes máquinas a través de una red se llama DCOM.
Esto se implementa mediante la creación de una instancia de la interfaz que se ve exactamente como el original. Pero todos los métodos de la interfaz son en realidad sustitutos que hacen el trabajo de ordenar la llamada. Este es el proxy. En el otro extremo del cable hay un sustituto que parece exactamente como la interfaz, pero hace el trabajo contrario. Este es el talón. El proxy y el apéndice trabajan juntos para crear la ilusión de que está haciendo una llamada a un método simple en su programa.
El trabajo principal del proxy consiste en serializar los argumentos de la llamada al método en un búfer de memoria o paquete de red. Esto puede ser bastante trivial, especialmente cuando utiliza punteros a estructuras de tamaño variable. COM necesita ayuda para hacerlo bien y ese es el trabajo de su proyecto FooPS. Cuando ejecuta midl.exe en su archivo .idl, midl autogenera el código de las definiciones de la interfaz para implementar el proxy y el stub. A menudo, esto es lo suficientemente bueno, pero es posible que deba implementar el suyo propio si las palabras clave incorporadas en midl no son suficientes para describir sus datos.
Por último, pero no menos importante, Windows proporciona un Marshaller estándar que puede reunir interfaces simples. Diseñado para admitir el subconjunto de COM definido por COM Automation. En otras palabras, las interfaces que se derivan de IDispatch y solo usan tipos compatibles con Automatización. Solo necesita obtener las entradas de registro adecuadas para habilitarlo y no necesita el proxy/stub generado por midl. Y, por supuesto, si solo realiza llamadas simples en proceso en un hilo, tampoco lo necesitará. Esto es bastante común.
respuesta increíble ... hizo mi día :) – Houston
Es un código de proxy/código auxiliar, que contiene los controladores de datos no estándar necesarios para transferir datos entre diferentes departamentos (relacionados con los hilos). Se usa cuando la aplicación, que llama a su objeto COM, usa un modelo de subprocesamiento COM diferente. Había una opción en el asistente de ATL/COM para fusionar este código en la biblioteca principal. En muchos escenarios comunes, no tiene que preocuparse por ello (es decir, cuando su dll COM se ejecuta en el contexto del cliente), a menos que desee escribir un contador de referencias personalizadas.
Como @ebutusov dijo, * el proyecto PS contiene implementaciones para Proxy and Stub. No son estándar, sino que MIDL los genera para las interfaces exportadas desde su servidor ATL. Estas interfaces se declaran en el archivo * .IDL. La salida del proyecto es DLL. Puede leer this article para obtener más detalles.
Puede eliminar el proyecto PS de la solución en caso de que no defina ninguna interfaz personalizada en su archivo * .IDL o si define solo las interfaces que tienen modificadores duales y oleautomation. En ese caso, se utilizará un contador de referencias estándar.
Con el fin de ser capaz de hacer uso del contador de referencias de biblioteca de tipos estándar, uno tiene que registrar una librería de tipos (que se realiza de forma automática dado que está utilizando ATL)
- 1. ¿Qué es "x && foo()"?
- 2. Foo f = Foo(); // no hay función de coincidencia para la llamada a 'Foo :: Foo (Foo)' ... ¿eh?
- 3. var foo = foo || alerta (foo);
- 4. ¿De qué sirve decir "#define FOO FOO" en C?
- 5. ¿Qué significa esto? int foo = foo + 4;
- 6. Referencia estándar para int foo = foo
- 7. char * foo vs char * foo
- 8. Es Foo * f = new Foo buen código de C++
- 9. ¿qué quiere decir FOO?
- 10. Foo no se puede convertir a Foo
- 11. ¿Por qué Amazon S3 no sirve automáticamente /foo/index.html cuando solicito/foo o/foo /?
- 12. ¿Hay alguna diferencia entre [& foo] {...} captura y [foo] {...} captura si 'foo' es una variable de referencia?
- 13. ¿Por qué no funciona "git log - foo" para el archivo eliminado foo?
- 14. Diferencia entre "struct foo *" y "foo *" donde foo es una estructura?
- 15. ¿Qué es esto de "foo. (Bar.Baz)" en el código Go?
- 16. Velocidad de PHP: ¿qué es más rápido? if (isset ($ foo)) OR if ($ foo == true)
- 17. 'var foo = función ...' y 'la función foo() ...'
- 18. Para foo bar, o no para foo bar: esa es la pregunta
- 19. ¿Es el reemplazo de comando $ (foo) bashism?
- 20. ¿Por qué compila erlang: foo()?
- 21. ¿Qué significa __PACKAGE __-> {foo}?
- 22. ¿Por qué "foo" .toString() no es lo mismo que toString.call ("foo")?
- 23. Diferencia entre clase foo y clase foo (objeto) en Python
- 24. ¿Qué significa (myVar && foo()) en JavaScript?
- 25. En jQuery, ¿el selector $ ('[id = foo]') es menos eficiente que $ ('# foo')?
- 26. ¿Cuál es el nombre de una función [foo, bar] = ["foo", "bar"]?
- 27. Absoluto ("/ foo") y relativo ("../foo") nombres de archivo. ¿Cómo se llama la categoría "foo"?
- 28. polimorfismo C++ ((X *) y) -> foo() vs ((X) * y) .foo()
- 29. 'argumento': conversiones ambiguas de 'Foo * const' a
- 30. ¿Cuándo os.environ ['foo'] no coincide con os.getenv ('foo')?
"PS" significa proxy/stub, probablemente alguien sepa más que yo lo que significa. – ybungalobill