stiamo scavando attraverso alcuni veramente vecchio C++/CLI-Code (Beta vecchia sintassi .NET) ed erano un po 'sorpreso di vedere qualcosa di simile:Perché printf funziona con stringhe gestite?
System::String ^source("Test-String");
printf("%s", source);
Il programma stampa correttamente
Test-String
Ci chiediamo, perché è possibile passare la sorgente di stringhe gestite a printf
- e ancora più importante: Perché funziona? Non mi aspetto che sia un po 'la convenienza di funzionalità dal compilatore perché il seguente non funziona:
System::String ^source("Test-String");
char pDest[256];
strcpy(pDest, source);
Questo produce una (in qualche modo atteso) la compilazione di errore che dice che System::String^
non possono essere convertiti in const char*
. Quindi la mia unica spiegazione è che il passaggio di un riferimento gestito a una va_list supera tutti i controlli del compilatore e induce il codice nativo a utilizzare un puntatore nell'heap gestito. Poiché System::String
è rappresentato come un char
-Array in memoria, printf
potrebbe funzionare. Oppure il compilatore converte in pin_ptr
e lo passa a printf
.
Non mi aspetto che esegua il marshalling automatico dello String^
su char*
, perché ciò comporterebbe una perdita di memoria non valida senza alcun riferimento all'indirizzo di memoria effettivo.
Sappiamo che questa non è una buona soluzione e i vari metodi di marshalling introdotti dalle versioni successive di Visual Studio forniscono un approccio migliore, ma sarebbe molto interessante capire cosa sta realmente accadendo qui.
Grazie!
Quindi forse la domanda è, * perché * il compilatore lo trasforma in IL? Da quando 'printf' è una funzione gestita? Perché è P/invocandolo? Perché non lo chiama come qualsiasi altra funzione C++ nativa? –
@CodyGray Il mio sospetto è che lo stiate invocando perché il compilatore vede qualcosa che deve passare attraverso il marshaller, per prima cosa. Verificherò e scriverò qualcosa di più completo in un po '. – vcsjones
Grazie per le risposte finora! Per me l'unica vera differenza tra strcpy e sprintf riguardo le stringhe gestite è il fatto che sprintf accetta una variabile arg-list e strcpy no. E forse questa è la ragione per il codice IL. – Excelcius