estamos cavando actualmente a través de la muy antigua C++/CLI-Code (sintaxis antigua .NET Beta) y eran un poco sorprendido de ver algo como esto:¿Por qué printf funciona con cadenas gestionadas?
System::String ^source("Test-String");
printf("%s", source);
El programa emite correctamente
Test-String
Nos estamos preguntando, ¿por qué es posible pasar la fuente de cadena administrada a printf
? Y más importante aún: ¿Por qué funciona? No me esperaba que fuera un poco de comodidad-estelar por el compilador debido a que el siguiente no funciona:
System::String ^source("Test-String");
char pDest[256];
strcpy(pDest, source);
Esto produce una (de alguna manera esperada) la compilación de error que indica que System::String^
no se puede convertir en const char*
. Así que mi única explicación real es que pasar una referencia administrada a una va_list sobrepasa todas las comprobaciones del compilador y engaña al código nativo para que use un puntero en el montón administrado. Como System::String
se representa de forma similar a char
-Array en memoria, printf
puede funcionar. O el compilador se convierte en pin_ptr
y lo pasa a printf
.
No espero que marque automáticamente el String^
en char*
, porque eso daría como resultado una pérdida de memoria incorrecta sin ninguna referencia a la dirección de memoria real.
Sabemos que esta no es una buena solución y los diversos métodos de clasificación introducidos por las últimas Visual Studio-Versions proporcionan un enfoque mucho mejor, pero sería muy interesante entender lo que realmente está sucediendo aquí.
Gracias!
Así que tal vez la pregunta es, * ¿por qué * es el compilador convirtiéndolo en esa IL? ¿Desde cuándo 'printf' es una función administrada? ¿Por qué es P/Invocarlo? ¿Por qué no lo está llamando como cualquier otra función nativa de C++? –
@CodyGray Mi sospecha es que está invocando porque el compilador ve que algo tiene que pasar primero por el marcador. Verificaré y escribiré algo más completo en un momento. – vcsjones
¡Gracias por las respuestas hasta ahora! Para mí, la única diferencia real entre strcpy y sprintf con respecto a las cadenas administradas es el hecho de que sprintf toma una variable arg-list y strcpy no. Y tal vez esa es la razón del código IL. – Excelcius