chúng tôi đang đào bới một số C++/CLI-Mã (Cũ Cú pháp NET Beta) thực sự cũ và là một chút ngạc nhiên khi thấy một cái gì đó như thế này:Tại sao printf hoạt động với chuỗi được quản lý?
System::String ^source("Test-String");
printf("%s", source);
Chương trình kết quả đầu ra một cách chính xác
Test-String
Chúng tôi đang tự hỏi, tại sao có thể chuyển nguồn chuỗi được quản lý đến printf
- và quan trọng hơn: Tại sao nó hoạt động? Tôi không mong đợi nó có một số tiện-tính năng của trình biên dịch vì những điều sau đây không làm việc:
System::String ^source("Test-String");
char pDest[256];
strcpy(pDest, source);
này tạo ra một (bằng cách nào đó dự kiến) biên dịch báo lỗi nói rằng System::String^
không thể được chuyển đổi sang const char*
. Vì vậy, giải thích thực sự duy nhất của tôi là chuyển một tham chiếu được quản lý đến một va_list vượt qua tất cả các trình biên dịch kiểm tra và thủ thuật mã gốc vào sử dụng một con trỏ vào vùng quản lý. Kể từ System::String
được thể hiện tương tự như một char
-Array trong bộ nhớ, printf
có thể hoạt động. Hoặc trình biên dịch chuyển đổi thành pin_ptr
và chuyển nó tới printf
.
Tôi không mong đợi nó sẽ tự động sắp xếp String^
đến char*
, vì điều đó sẽ dẫn đến rò rỉ bộ nhớ kém mà không có tham chiếu đến địa chỉ bộ nhớ thực. Chúng tôi biết rằng đây không phải là một giải pháp tốt và các phương pháp marshalling khác nhau được giới thiệu bởi Visual Studio-Phiên bản sau cung cấp một cách tiếp cận tốt hơn nhưng nó sẽ rất thú vị để hiểu những gì đang thực sự xảy ra ở đây.
Cảm ơn!
Vì vậy, có lẽ câu hỏi là, * tại sao * là trình biên dịch biến nó thành IL đó? Kể từ khi nào là 'printf' một hàm được quản lý? Tại sao nó P/Gọi nó? Tại sao nó không gọi nó giống như bất kỳ chức năng C++ gốc nào khác? –
@CodyGray Nghi ngờ của tôi là nó chọc lỗ nó bởi vì trình biên dịch thấy một cái gì đó cần phải đi qua marshaller, đầu tiên. Tôi sẽ xác minh và viết một cái gì đó toàn diện hơn trong một chút. – vcsjones
Cảm ơn câu trả lời cho đến nay! Với tôi sự khác biệt thực sự duy nhất giữa strcpy và sprintf liên quan đến chuỗi quản lý là một thực tế là sprintf có một biến arg-list và strcpy thì không. Và có lẽ đó là lý do cho mã IL. – Excelcius