Compartir a través de


Este artículo proviene de un motor de traducción automática.

CLR Inside Out

Procedimientos recomendados de interoperabilidad de código administrado Y nativo

Jesse Kaplan

Contenido

¿Cuando es apropiado interoperabilidad administrada de nativo?
Tecnologías de interoperabilidad: opciones de tres
Tecnologías de interoperabilidad: P/Invoke
Tecnologías de interoperabilidad: interoperabilidad COM
Interoperabilidad de las tecnologías: C + c++ / CLI
Consideraciones sobre la arquitectura de la interoperabilidad
Diseño de la API y experiencia de desarrollo
Rendimiento y la ubicación de su límite de interoperabilidad
Administración de vigencia

En cierto modo, puede parecer impar ver una columna como este aparezcan una en MSDN Magazine 2009 anticipado, admiten la interoperabilidad de código nativo y administrado en Microsoft .NET Framework, en más o menos el mismo formulario, desde la versión 1.0 de 2002. Además, puede fácilmente encontrar documentos de API y herramienta de nivel detallado y de miles de páginas de documentos de soporte detallado. Aunque la parte que falta en todas de este es completa y de alto nivel guía arquitectura que describe cuándo utilizar la interoperabilidad, ¿qué arquitectura consideraciones que debe tener en cuenta, y qué tecnología de interoperabilidad para utilizar. Esto es la separación que voy a empezar a rellenar aquí.

¿Cuando es apropiado interoperabilidad administrada de nativo?

No ha habido una gran escrita sobre cuando es adecuado utilizar la interoperabilidad nativo administrado y gran parte de lo que se encuentra en el tema está en conflicto. En ocasiones, la guía no depende experiencia práctica real, o bien. Por lo que antes empezar, me estado permite todo lo que estoy escribiendo sobre hoy se orientación que hemos desarrollado basa en las experiencias el equipo de interoperabilidad tuvo ayudado a clientes internos y externos de todos los tamaños.

En sintetiza esta experiencia, nos reunir tres productos que sirven como excelentes ejemplos de usos correctas de interoperabilidad y un representante de conjunto de los tipos de usos de la interoperabilidad. Visual Studio Tools para Office es el conjunto de herramientas extensibilidad administrada para Office y es la aplicación primera que pienso cuando pienso en interoperabilidad. Representa el uso clásico de la interoperabilidad, una aplicación nativa grande que desea habilitar extensiones administradas o complementos. A continuación en mi lista es Windows Media Center, una aplicación que se creó desde cero hasta que administra un mixto y aplicación nativa. Windows Media Center se desarrolló mediante código administrado principalmente con algunas partes, los que tratar directamente con el sintonizador de TV y otros controladores de hardware, integrado en código nativo. Finalmente hay expresiones diseño, administrado de una aplicación con un grande y preexistente código nativo base que desea aprovechar nuevas tecnologías, en este caso, Windows Presentation Foundation (WPF), para ofrecer una experiencia de usuario de próxima generación.

Las tres razones más comunes para utilizar la interoperabilidad de direcciones de estas tres aplicaciones: para permitir la extensibilidad administrada de aplicaciones nativas ya existentes, para permitir que la mayor parte de una aplicación para aprovechar las ventajas del código administrado al escribir aún las piezas de nivel inferior en código nativo y para agregar una experiencia de usuario diferenciados, de próxima generación a una aplicación nativa existente.

En el pasado, orientación disponible podría ha sugerido simplemente volver a escribir toda la aplicación en el código administrado en estos casos. Intenta seguir este consejo y ver cuántas personas simplemente se niegan a seguir ha realizado claro que esto no simplemente es una opción para la mayoría de las aplicaciones existente. Interoperabilidad va a ser la tecnología fundamental que permite a los programadores mantener su inversión existente en código nativo aunque sigan pudiendo aprovechar el nuevo entorno administrado. Si piensa volver a escribir la aplicación por otros motivos, código administrado puede ser una buena elección para usted. Pero generalmente no desea volver a escribir la aplicación simplemente para utilizar nuevas tecnologías administradas y evitar la interoperabilidad.

Tecnologías de interoperabilidad: opciones de tres

Hay tres tecnologías principales de interoperabilidad disponibles en .NET Framework, y que uno puede elegir se determinará en parte por el tipo de API que se utiliza para la interoperabilidad y en parte por los requisitos y necesita controlar el límite. Invoke de plataforma, o P/Invoke, es principalmente una administrado a nativo interoperabilidad tecnología que permite llamar a API nativas de estilo C desde código administrado. Interoperabilidad COM es una tecnología que permite a consumir nativas interfaces COM desde código administrado o exportar interfaces COM nativas de API administradas. Por último es C + c++ / CLI (conocido como C++ administrado), que permite crear ensamblados que contienen una mezcla de C++ nativo y administrado código compilado y está diseñado para servir como puente entre código nativo y administrado.

Tecnologías de interoperabilidad: P/Invoke

P/Invoke es el más sencillo de las tres tecnologías y se diseñó principalmente para proporcionar acceso administrado a las API C de estilo. Con P/Invoke es necesario ajustar cada API individualmente. Esto puede ser una muy buena opción si tiene unas pocas API para ajustar y sus firmas no son muy complejas. P/Invoke Obtiene considerablemente más difíciles a utilizar, sin embargo, si las API no administradas tienen una gran cantidad de los argumentos que no tienen una buena equivalentes administrados, como estructuras de longitud variable, anular * s, uniones superpuestas y así sucesivamente.

Las bibliotecas de clase base (BCL) de .NET Framework contienen muchos ejemplos de API que son contenedores realmente sólo gruesas alrededor de un gran número de declaraciones P/Invoke. Casi toda la funcionalidad de .NET Framework que se ajusta API no administradas de Windows se construye mediante P/Invoke. De hecho, incluso formularios Windows Forms se basa casi por completo en el ComCtl32.dll nativo mediante P/Invoke.

Hay unos pocos recursos muy valiosos que pueden realizar mediante P/Invoke mucho más fácil. En primer lugar, pinvoke el sitio Web. red tiene un wiki, originalmente configurar por ADAM Nathan desde el equipo de interoperabilidad de CLR, que tiene un gran número de firmas por el usuario ha contribuido para una amplia variedad de API de Windows común.

Hay también un muy útil Visual Studio complemento que facilita la consulte pinvoke. NET desde dentro de Visual Studio. Para API que no quedan cubiertas en pinvoke. NET, si están de sus propias bibliotecas o de otra persona, el equipo de interoperabilidad ha publicado un P/Invoke herramienta de generación de firma denomina el Asistente para interoperabilidad P/Invoke, que crea automáticamente las firmas de API nativas basado en un archivo de encabezado. La captura de pantalla correspondiente muestra la herramienta en acción.

fig01.gif

crear firmas en el Asistente para interoperabilidad P/Invoke

Tecnologías de interoperabilidad: interoperabilidad COM

Interoperabilidad COM permite a las interfaces COM desde código administrado de consumir o exponer API administradas como interfaces COM. Puede utilizar la herramienta TlbImp para generar una biblioteca administrada que expone administra interfaces para comunicarse con un tlb de COM específica. Y TlbExp realiza la tarea opuesta y generará un tlb COM con interfaces que corresponden a los tipos ComVisible en un ensamblado administrado.

Interoperabilidad COM puede ser una solución muy buena si ya está utilizando COM dentro de la aplicación o como su modelo de extensibilidad. También es la forma más fácil mantener la semántica de COM de alta fidelidad entre el código nativo y administrado el código. En concreto, interoperabilidad COM es una excelente opción si es interoperar con un componente de Visual Basic 6.0-basado, como el CLR sigue básicamente las mismas reglas COM de Visual Basic 6.0.

Interoperabilidad COM es menos útil si la aplicación no ya utiliza COM internamente, o si no necesita plena fidelidad de semántica de COM y su rendimiento no es aceptable para la aplicación.

Microsoft Office es el ejemplo más visibles de una aplicación que utiliza interoperabilidad COM como el puente entre código nativo y administrado. Office es un candidato excelente para la interoperabilidad COM, como tiempo utilizó COM como su mecanismo de extensibilidad y se suele utilizar en Visual Basic para Aplicaciones (VBA) o Visual Basic 6.0.

Originalmente Office dependía totalmente TlbImp y el ensamblado de interoperabilidad fino como su modelo de objetos administrados. A lo largo del tiempo, sin embargo, el Visual Studio Tools para Office (VSTO) producto se ha integrado en Visual Studio, que ofrece un modelo de desarrollo más rica y completas que incorporar muchos de los principios descritos en esta columna. Cuando se utiliza el producto VSTO hoy en día, a veces es tan fácil olvidar que la interoperabilidad COM está atendiendo como la base de VSTO ya que es olvidarse que P/Invoke es la base de gran parte de la BCL.

Interoperabilidad de las tecnologías: C + c++ / CLI

C + c++ / CLI está diseñado para ser un puente entre el mundo nativo y administrado, y permite compilar C++ nativo y administrado en el mismo ensamblado (incluso la misma clase) y realizar llamadas de C++ estándar entre las dos partes del ensamblado. Cuando se utiliza C + c++ / CLI, puede elegir la parte del ensamblado que desee administrar y que desea se nativo. El ensamblado resultante es una mezcla de MSIL (lenguaje intermedio de Microsoft, se encuentra en todos los ensamblados administrados) y código de ensamblado nativo. C + c++ / CLI es una tecnología de interoperabilidad muy eficaz que ofrece un control casi total sobre el límite de interoperabilidad. La desventaja es que obliga a tomar el control casi completo sobre el límite.

C + c++ / CLI puede ser un puente buena si es estática de tipo de comprobación es necesario, si el rendimiento estricto es un requisito, y si necesita finalización más predecible. Si P/Invoke o interoperabilidad COM satisface sus necesidades, son generalmente más sencillo usar, especialmente si los desarrolladores no están familiarizados con C++.

Hay algunas cosas a tener en cuenta cuando considere C + c++ / CLI. Lo primero que recordar es que si piensa utilizar C + c++ / CLI para proporcionar una versión más rápida de la interoperabilidad COM, interoperabilidad de COM es más lento que C++ / CLI porque lleva mucho trabajo en su nombre. Si sólo flexible usar COM en la aplicación y no requieren plena fidelidad de interoperabilidad COM, a continuación, es un buen equilibrio.

Si, sin embargo, se utiliza una gran parte de las especificaciones de COM, es probable que encontrará que una vez que agrega a las partes de la semántica de COM necesite en el C + + / solución CLI, se han hecho mucho trabajo y tendrá rendimiento no mejor que lo que se proporciona con interoperabilidad COM. Varios equipos de Microsoft han pasado abajo este camino sólo para darse cuenta esta y mover volver a la interoperabilidad COM.

La segunda consideración importante para el uso de C + c++ / CLI es Recuerde que esto es sólo pretende ser un puente entre los ámbitos nativos y administrados y no pretende ser una tecnología que se utilizar para escribir la mayor parte de la aplicación. Es posible ciertamente, para ello, pero encontrará que la productividad del desarrollador es mucho menor en un C++ puro o puro C# y entorno de Visual Basic y que la aplicación se ejecutará mucho más lentamente a inicio. Por lo que cuando se utiliza C + c++ / CLI, compilar sólo los archivos que necesita con el modificador / CLR y utilice una combinación de puro de ensamblados administrado o puro nativo para crear la funcionalidad principal de la aplicación.

Consideraciones sobre la arquitectura de la interoperabilidad

Una vez haya decidido utilizar la interoperabilidad en la aplicación y decide qué tecnología para utilizar, existen algunas consideraciones de alto nivel al diseñar la solución, incluidos el diseño de la API y la experiencia de programador para aquellos con el límite de interoperabilidad de codificación. También se tienen en cuenta donde colocar las transiciones administradas nativas y el impacto de rendimiento que esto puede tener en la aplicación. Y por último, deberá tener en cuenta la administración de vigencia y si es necesario hacer nada para salvar las diferencias entre el mundo de recolección del entorno administrado y la administración de vigencia manual y determinista del mundo nativo.

Diseño de la API y experiencia de desarrollo

¿Cuando pensando en el diseño de la API, hay varias preguntas que debe preguntarse: que se va a ser codificación frente a la capa de interoperabilidad y debe optimizar para mejorar su experiencia o para reducir el costo de creación del límite? ¿Son los desarrolladores de codificación con este límite los mismos que escribir el código nativo? ¿Son otros desarrolladores de su organización? ¿Son los desarrolladores ampliar la aplicación o se utilizando como un servicio de terceros? ¿Cuál es su nivel de sofisticación? ¿Son cómodo con paradigmas nativos o se sólo Feliz al escribir código administrado?

Las respuestas a estas preguntas le ayudarán a determinar acaban hacia arriba en el espectro de entre un envoltorio muy sobre el código nativo y un modelo de enriquecido objetos administrados que utiliza el código nativo en segundo plano. Con un contenedor de baja interactividad, todos los paradigmas de nativos se impresión a sangre mediante y, a los desarrolladores será muy en cuenta el límite y el hecho de que son de codificación con una API nativa. Con un contenedor más grueso casi por completo puede ocultar el hecho de que código nativo se encuentra en la imagen, el sistema de archivos las API de la BCL son un excelente ejemplo de una capa de interoperabilidad muy delgada que proporciona un modelo de objeto administrado participante.

Rendimiento y la ubicación de su límite de interoperabilidad

Antes de que se emplee demasiado tiempo optimizar su aplicación, es importante que determinar si o no tiene un problema de rendimiento de interoperabilidad. Muchas aplicaciones utilizan interoperabilidad en las secciones críticas de rendimiento y necesario prestar atención. Pero muchos otros se va a estar usando la interoperabilidad en respuesta a los clics del mouse (ratón) del usuario y no verán decenas, cientos o incluso miles de interoperabilidad transiciones causar retrasos a sus usuarios. Dicho esto, al echa un vistazo al rendimiento de la solución de interoperabilidad, debe tener en cuenta dos objetivos: reducir el número de interoperabilidad transiciones marca y reducir la cantidad de datos que se pasan en cada transición.

Una transición determinada interoperabilidad con una cantidad determinada de cruce de datos entre el mundo nativo y administrado básicamente va a tener un costo fijo. Este costo fijo será diferente que depende de la opción de tecnología de interoperabilidad, pero si realiza esa opción porque necesita las características de esa tecnología, a continuación, no podrá cambiarlo. Esto significa el enfoque se debe reducir la chattiness del límite y, a continuación, reducir la cantidad de datos atraviesen.

Cómo hacerlo depende en gran medida la aplicación. Pero una estrategia común y adaptable, con la que muchos han tenido éxito es mover el límite de aislamiento escribiendo un fragmento de código en el lado del límite que define la interfaz de ocupado y a la sobrecarga de datos. La idea básica es escribir una capa de abstracción que lotes de llamadas en la interfaz muy ocupada o, incluso mejor, al mover la parte de la lógica de aplicación que necesita para interactuar con esta API a través del límite y sólo pasar las entradas y los resultados a través del límite.

Administración de vigencia

Las diferencias en administración de vigencia entre los ámbitos administrados y nativos a menudo es uno de los mayores desafíos de interoperabilidad de los clientes. La diferencia fundamental entre el sistema de en función de la colección de elementos no utilizados de .NET Framework y el sistema manual y determinista en el mundo nativo puede suele manifestarse de forma sorprendente que puede ser difícil de diagnosticar.

El primer problema puede que observe en una solución de interoperabilidad es la cantidad prolongada de tiempo algunos objetos administrados mantenga en para sus recursos nativos incluso tras el ámbito administrado ha terminado de usarlas. Esto a menudo causa problemas cuando el recurso nativo es muy escasos y depende de que se liberan tan pronto como llaman terminado de utilizar (conexiones de base de datos son un buen ejemplo de esto).

Cuando estos recursos no son escasos, se pueden simplemente depender el recolector de elementos llamar al finalizador de un objeto y permitir que esa versión de finalizador los recursos nativos (implícita o explícitamente). Cuando los recursos son escasos, el patrón dispose administrado puede ser muy útil. En lugar de exponer objetos nativos directamente al código administrado, se debe colocar al menos un envoltorio alrededor de ellas que implementa IDisposable y sigue el patrón dispose estándar. De este modo, si encuentra agotamiento de recursos que un problema, puede explícitamente deshacerse de estos objetos en el código administrado y liberar los recursos tan pronto como haya terminado con ellos.

El problema de administración de vigencia segundo que normalmente afecta a las aplicaciones es uno que los desarrolladores perciben a menudo como una colección de basura stubborn: mantiene aumenta su uso de memoria, pero por alguna razón los elementos no utilizados se ejecuta con poca frecuencia recolector y objetos se mantienen activas. A menudo se siga agregando las llamadas a GC.Collect para forzar el problema.

La raíz de este problema es normalmente que hay una gran cantidad de muy pequeños objetos administrados que retener y mantener estructuras de datos nativo de actividad, muy grandes. Lo que sucede es que el recolector de elementos no utilizados se ajusta y intenta evitar perder tiempo realizando innecesarios o unhelpful colecciones. Y, así como examinar la presión de memoria actual del proceso, examina cuánto memoria cada colección de elementos no utilizados libera al decidir si desea realizar otra.

Cuando se ejecuta en este escenario, sin embargo, verá que cada colección sólo libera una pequeña cantidad de memoria (recuerde que sólo conoce sobre cuánta memoria administrada liberado) y no se da cuenta de que la liberación de los objetos pequeños puede disminuir significativamente a la presión general. Esto conduce a una situación donde colecciones menos y menos suceder incluso cuando mantiene aumenta el uso de memoria.

La solución a este problema consiste en proporcionar sugerencias al recolector de elementos no utilizados como el costo de memoria real de cada uno de estos contenedores administrados pequeños sobre los recursos nativos. Hemos agregado un par de API de .NET Framework 2.0 que permite hacer exactamente eso. Puede utilizar el mismo tipo de los contenedores que utiliza para agregar los patrones de dispose a escasos recursos pero repurpose para proporcionar sugiere al recolector de elementos no utilizados en lugar de tener explícitamente que liberar los recursos manualmente.

En el constructor de este objeto basta con llamar al método GC.AddMemoryPressure y pasar en el costo aproximado en memoria nativo del objeto nativo. Se puede, a continuación, llamar a GC.RemoveMemoryPressure de método de finalizador del objeto. Este par de llamadas le ayudará a comprender el costo es true de estos objetos y la memoria real liberado al liberarlos el recolector de elementos. Tenga en cuenta que es importante para asegurarse de que equilibrar las llamadas al agregar o RemoveMemoryPressure perfectamente.

El tercer común desconectar en duración administración entre los ámbitos nativos y administrados no es lo mucho sobre la administración de recursos individuales o objetos pero en lugar de todo ensamblados o bibliotecas. Bibliotecas nativas pueden se descarga fácilmente a una aplicación es hacer con ellos, pero administra bibliotecas no se descargó por sí solos. En su lugar, el CLR tiene unidades de aislamiento denominadas dominios de aplicación que se pueden descargar individualmente y se limpiar todos los ensamblados, objetos y subprocesos incluso que se ejecutan en ese dominio cuando se descarga. Si está creando una aplicación nativa y están acostumbrados a descargar los complementos cuando haya terminado con ellos, encontrará que con diferentes dominios de aplicación para cada uno de los complementos administrados le proporcionará la misma flexibilidad que tenía en descargar bibliotecas nativas individuales.

Envíe sus preguntas y comentarios a clrinout@Microsoft.com.

Jesse Kaplan es actualmente el administrador de programas de interoperabilidad administrada y nativa para el equipo CLR de Microsoft. Sus anteriores responsabilidades incluyen compatibilidad y extensibilidad.