2010-11-12 25 views
8

¡Estoy pensando en utilizar los caracteres # @! en algunas interfaces COM nuestro sistema genera. La biblioteca de tipo COM también se exporta a .NET. ¿Me causarán problemas esos personajes más adelante?Caracteres no alfanuméricos en los nombres de interfaz COM/.NET

Lo he probado durante la mayor parte del día de hoy, y todo parece estar bien. Nuestro sistema continúa funcionando como siempre lo hizo.

La razón por la que soy cauteloso es que esos caracteres son ilegales en MIDL, que usa la sintaxis C para los nombres de tipo. Pero no utilizamos MIDL: construimos nuestras bibliotecas de tipos con ICreateTypeInfo e ICreateTypeLib. Parece que es solo una restricción MIDL, y COM y .NET están contentos con los caracteres no alfanuméricos. Pero tal vez haya algo que no sé ...

+4

Buena pregunta porque demuestra minuciosidad. Me gustan las preguntas como esta porque significa que al menos algunos programadores intentan anticipar problemas con anticipación. –

Respuesta

2

Esto es lo que he encontrado.

Creo que no hay duda de que los nombres son legales a nivel binario en COM, ya que el nombre de una interfaz COM es su IID y el nombre del texto es solo documentación.

En el lado de .NET, la especificación relevante es la especificación de Common Language Infrastructure (ECMA-335, http://www.ecma-international.org/publications/standards/Ecma-335.htm). Me pregunto si .NET o Mono agregarán sus propias restricciones en la parte superior; hacerlo reduciría la interoperabilidad, pero esto es el mundo real

La sección 8.5.1 cubre nombres de tipos válidos en el sistema de tipos comunes, y simplemente dice que los nombres se comparan usando puntos de código. Es extraño que no diga nada sobre la composición de un nombre, solo cómo se comparan los nombres. Esta sección está parafraseada por MSDN en http://msdn.microsoft.com/en-us/library/exy17tbw%28v=VS.85%29.aspx, que dice que las únicas dos restricciones son (1) nombres de tipo "codificados como cadenas de caracteres Unicode (16 bits)" y (2) no pueden contener un 0x0000 incrustado.

He citado el bit sobre Unicode de 16 bits, en lugar de parafrasearlo, porque usa un lenguaje impreciso. Presumiblemente, el autor de esa página significaba UTF-16. En cualquier caso, ECMA-335 especifica la comparación byte por byte, y no hace mención de Unicode (con respecto a los nombres de tipo), y tampoco prohíbe los ceros incrustados. Quizás .NET se haya desviado del CTS aquí, aunque lo dudo. Lo más probable es que el autor de esta página de MSDN pensara en los lenguajes de programación cuando lo escribió.

La especificación de lenguaje común (también definida en ECMA-335) define las reglas para los identificadores en el código fuente. Los identificadores no son directamente relevantes para mi pregunta porque mis nombres de tipo internos nunca aparecen en el código fuente, pero lo analicé de inmediato. El CLS es un subconjunto del CTS, y como tal sus restricciones no son necesariamente parte del CTS más amplio. La Regla 4 de CLS dice que los identificadores deben seguir las reglas del Anexo 7 del Informe Técnico 15 del Estándar Unicode 3.0 - ver http://www.unicode.org/reports/tr15/tr15-18.html. Ese documento también es un poco vago, ya que se refiere a "otra letra" y "signos de puntuación del conector", pero no los define. Esto ayudó: http://notes.jschutz.net/topics/unicode/.

La sección 8.5.1 de la especificación ECMA incluye una nota no normativa de que un consumidor de CLS (como C# o el explorador de tipo Visual Studio, supongo) "no necesita consumir tipos que violen la regla 4 de CLS". los nombres de interfaz infringen esta Regla 4. Esta nota parece implicar que un tipo válido puede tener un nombre que viola la regla 4, y que un consumidor de CLS debe aceptar el nombre falso o ignorarlo de forma segura. (El navegador de tipo Visual Studio lo muestra sin quejarse).

Por lo tanto, mis nombres de tipos propuestos son generalmente ilegales en el código fuente. Pero tenga en cuenta que la sección 10.1 (sobre identificadores en el CLS) dice "Dado que sus reglas se aplican solo a los artículos exportados a otros idiomas, los miembros privados o no exportados desde un ensamblado pueden usar cualquier nombre que elijan"

¡Concluyo que es seguro usar los personajes # @! en mis nombres de tipo siempre y cuando permanezcan en el dominio binario y nunca tengan que aparecer en el código fuente ni fuera del ensamblaje. Y, de hecho, nunca se usan fuera del servidor COM.

Una palabra sobre el futuro-proofing ... El CTS prácticamente no tiene nada que decir sobre la composición de los nombres de los tipos, a pesar de tener una sección llamada "Nombres válidos" (sección 8.5.1). Podrían cambiar eso en el futuro, pero esta especificación amplia y liberal nos ha invitado a todos a hacer lo que nos gusta. Si los diseñadores de CTS hubieran querido dejar espacio para el cambio, seguramente habrían incorporado alguna provisión para eso, o al menos hubieran sido menos generosos.

+0

Bonito escribir. Tienes un error tipográfico, creo que te refieres a ECMA-335. Mi investigación siguió este mismo hilo. Si bien podría sopesar los pros y los contras de manera diferente, harías un buen caso. Mis argumentos restantes en contra son Off Topic, así que en su lugar, permítanme compartir esta referencia de apoyo. La sección 5.3 de la Partición II de ECMA-335 en la sintaxis del identificador de metadatos dice: "La sintaxis ILAsm permite el uso de cualquier identificador que pueda formarse utilizando el conjunto de caracteres Unicode. Para lograr esto, un identificador debe colocarse entre comillas simples". Parece a diferencia de MIDL, ILAsm permite y admite sus nombres inusuales. – jimhark

+0

Por favor, publique aquí si encuentra algún problema. Gracias. – jimhark

+0

Gracias, Jim :-) Me interesaría escuchar tus argumentos en contra ... podrían cubrir algo en lo que no había pensado. Y sí, publicaré aquí si hay novedades. (Y también arreglaré ese error tipográfico). –

1

Es interesante que parezca haber encontrado una laguna en la denominación del tipo COM. Microsoft restringe el uso de los caracteres '# @!' como identificadores en MIDL, pero no duplican esa restricción en las interfaces ICreateTypeInfo e ICreateTypeLib.

El uso de estos personajes funciona hoy en día, ¿cuál es el riesgo?

  1. Bueno, Microsoft podría ver esto como un error y 'arreglar' ICreateTypeInfo, ICreateTypeLib, .Net COM tipo de interoperabilidad, y/o .Net nombrar restricciones en la próxima versión.

  2. Está creando y utilizando una interfaz que no tiene definición válida de MIDL.

  3. Está utilizando nombres que probablemente tengan que cambiar si (cuando) pasa de COM a .Net. Aunque solo quiera crear un adaptador escriba en .Net no podrá reutilizar ninguno de los nombres "no válidos".

  4. ¿Es esto compatible con Mono y otras tecnologías no compatibles con Microsoft .Net ?

  5. Hay un montón de conocidos nombres válidos que podrían ser utilizados ( utilizar algo así como '_at_' en lugar de '@', etc.) para evitar cualquier posible problema futuro .

Si nada de esto te importa, entonces probablemente estarás bien. Pero sospecho que por el simple hecho de que hicieras esta pregunta, en cierto nivel no te parece "correcto".

Buena suerte.

+0

Aquí es donde estoy pensando: en COM, el nombre del texto no forma parte de la definición de tipo, es solo documentación. Entonces, en el nivel binario COM no hay problema. Pero no estoy lo suficientemente familiarizado con los detalles de bajo nivel de .NET para hacer la misma determinación para .NET. (Al menos, todavía no). –

+0

(Oops, pulse volver demasiado pronto.) El producto ya está mucho en .NET, por lo que el ángulo de .NET es un problema real en la actualidad. Sin embargo, los nombres de la interfaz nunca aparecen en el código fuente; estas interfaces solo se usan internamente y son cargadas por ITypeLib, etc. (Los comentarios de otra persona sobre ese tema desaparecieron misteriosamente de SO el otro día ... tal vez porque no voté su respuesta o algo así.) –

+0

Microsoft no va a cambiar el comportamiento de ICreateTypeInfo, etc.en esta última etapa del juego. No estoy tan seguro acerca de .NET, y ciertamente no estoy seguro de Mono. –

Cuestiones relacionadas