obecnie kopanie przez jakiś naprawdę starych C++/CLI-Code (Stary Składnia .NET Beta) i były nieco zaskoczony, aby zobaczyć coś takiego:Dlaczego printf działa z zarządzanymi ciągami?
System::String ^source("Test-String");
printf("%s", source);
Program poprawnie wyprowadza
Test-String
Zastanawiamy się, dlaczego można przekazać zarządzane źródło ciągu do printf
- i co ważniejsze: Dlaczego to działa? Nie spodziewam się, że będzie trochę wygoda-cecha przez kompilator ponieważ następuje nie działa:
System::String ^source("Test-String");
char pDest[256];
strcpy(pDest, source);
Daje to (w jakiś sposób oczekiwany) sporządzaniu błąd mówiąc, że System::String^
nie mogą być konwertowane do const char*
. Moim jedynym prawdziwym wytłumaczeniem jest to, że przekazanie zarządzanego odwołania do va_list przewyższa wszystkie kontrole kompilatora i powoduje, że natywny kod wykorzystuje wskaźnik do zarządzanej sterty. Ponieważ System::String
jest reprezentowany podobnie do char
-Array w pamięci, może działać printf
. Lub kompilator konwertuje na pin_ptr
i przekazuje go do printf
.
Nie oczekuję, że automatycznie pobierze sygnał String^
do char*
, ponieważ może to spowodować nieszczelny wyciek pamięci bez odniesienia do rzeczywistego adresu pamięci.
Wiemy, że nie jest to dobre rozwiązanie, a różne metody zestawiania wprowadzane przez późniejsze wersje Visual Studio-Versions zapewniają lepsze podejście, ale byłoby bardzo interesująco zrozumieć, co się tutaj dzieje.
Dzięki!
Może więc pytanie brzmi: * dlaczego * jest kompilatorem zamieniającym go w IL? Od kiedy to 'printf' jest funkcją zarządzaną? Dlaczego to P/Inwokowanie? Dlaczego nie nazywa się tego jak inną natywną funkcją C++? –
@CodyGray Podejrzewam, że to POTWIERDZANIE, ponieważ kompilator widzi, że najpierw musi przejść przez marshaller. Weryfikuję i piszę coś bardziej kompleksowego. – vcsjones
Dzięki za odpowiedzi do tej pory! Jedyna rzeczywista różnica między strcpy i sprintf dotycząca zarządzanych łańcuchów to fakt, że sprintf przyjmuje zmienną arg-list, a strcpy nie. I może to jest powód kodu IL. – Excelcius