Tôi nên biên dịch với / MD hoặc / MT?


126

Trong Visual Studio, có các cờ biên dịch / MD và / MT cho phép bạn chọn loại thư viện thời gian chạy C nào bạn muốn.

Tôi hiểu sự khác biệt trong triển khai, nhưng tôi vẫn không chắc nên sử dụng cái nào. Những ưu / nhược điểm là gì?

Một lợi thế cho / MD mà tôi đã nghe, là điều này cho phép ai đó cập nhật thời gian chạy, (như có thể khắc phục vấn đề bảo mật) và ứng dụng của tôi sẽ được hưởng lợi từ bản cập nhật này. Mặc dù với tôi, điều này gần như không phải là một tính năng: Tôi không muốn mọi người thay đổi thời gian chạy của mình mà không cho phép tôi thử nghiệm phiên bản mới!

Một số điều tôi tò mò về:

  • Làm thế nào điều này sẽ ảnh hưởng đến thời gian xây dựng? (có lẽ / MT chậm hơn một chút?)
  • Các tác động khác là gì?
  • Cái nào làm hầu hết mọi người sử dụng?

1
Thông tin và đề xuất khác có thể được tìm thấy trong: stackoverflow.com/questions/787216
Weidenrinde

Câu trả lời:


85

Bằng cách liên kết động với / MD,

  • bạn được tiếp xúc với các bản cập nhật hệ thống (tốt hay xấu),
  • khả năng thực thi của bạn có thể nhỏ hơn (vì nó không có thư viện được nhúng trong đó) và
  • Tôi tin rằng ít nhất là đoạn mã của một DLL được chia sẻ giữa tất cả các quy trình đang tích cực sử dụng nó (giảm tổng lượng RAM tiêu thụ).

Trong thực tế, tôi cũng thấy rằng khi làm việc với các thư viện nhị phân chỉ bên thứ ba được liên kết tĩnh được xây dựng với các tùy chọn thời gian chạy khác nhau, / MT trong ứng dụng chính có xu hướng gây ra xung đột thường xuyên hơn / MD (vì bạn Sẽ gặp rắc rối nếu thời gian chạy C được liên kết tĩnh nhiều lần, đặc biệt nếu chúng là các phiên bản khác nhau).


10
Các bit cập nhật hệ thống có phần giảm bởi SxS. EXE sẽ tuyên bố phiên bản CRT nào họ muốn (muốn, không nhận - các bản cập nhật bảo mật có thể ghi đè lên điều này)
MSalters

1
Điều này có nghĩa là nếu tôi biên dịch bằng MD và chương trình của tôi phụ thuộc vào một số dll, chương trình sẽ thất bại nếu nó chạy trên máy tính mà dll phụ thuộc không tồn tại?
gerrytan

5
@gerrytan: Có, bạn sẽ cần đảm bảo rằng các DLL phù hợp đang được sử dụng có mặt trên tất cả các máy tính muốn chạy phần mềm. Các giải pháp điển hình cho vấn đề này là yêu cầu người dùng cài đặt gói phân phối lại MSVC phù hợp hoặc sử dụng trình cài đặt thực hiện tất cả công việc.
Ông Fooz

@Royi Tôi không chắc nhưng tôi nghĩ /MTsẽ nhanh hơn một chút khi chạy vì ứng dụng của bạn không cần tìm kiếm triển khai chức năng thời gian chạy mỗi lần, tôi không phải là chuyên gia ở cấp độ này nhưng tôi khá chắc chắn về Các hệ điều hành sẽ lưu trữ các triển khai thời gian chạy để ứng dụng của bạn sẽ sử dụng phiên bản được lưu trong bộ nhớ cache, do đó, sự khác biệt sẽ không còn xa nữa, LƯU Ý rằng tôi đã đề cập rằng tôi không chắc chắn vì vậy đừng lấy nhận xét này làm đối số.
Ahmed Kamal

34

Nếu bạn đang sử dụng DLL thì bạn nên sử dụng CRT (/ MD) được liên kết động.

Nếu bạn sử dụng CRT động cho .exe của mình và tất cả các dll thì tất cả chúng sẽ chia sẻ một triển khai CRT duy nhất - điều đó có nghĩa là tất cả chúng sẽ chia sẻ một đống CRT duy nhất và bộ nhớ được phân bổ trong một .exe /. khác.

Nếu bạn sử dụng CRT tĩnh cho .exe của bạn và tất cả các dll thì tất cả họ sẽ nhận được một bản sao riêng của CRT - điều đó có nghĩa là tất cả họ sẽ sử dụng heap CRT của riêng họ để bộ nhớ phải được giải phóng trong cùng một mô-đun đã được phân bổ. Bạn cũng sẽ bị phình mã (nhiều bản sao của CRT) và chi phí thời gian chạy quá mức (mỗi heap phân bổ bộ nhớ từ HĐH để theo dõi trạng thái của nó và có thể nhận thấy chi phí hoạt động).


20

Tôi tin rằng mặc định cho các dự án được xây dựng thông qua Visual Studio là / MD.

Nếu bạn sử dụng / MT, khả năng thực thi của bạn sẽ không phụ thuộc vào DLL hiện diện trên hệ thống đích. Nếu bạn gói cái này trong trình cài đặt, nó có thể sẽ không thành vấn đề và bạn có thể đi bằng bất kỳ cách nào.

Tôi sử dụng / MT bản thân mình, để tôi có thể bỏ qua toàn bộ mớ hỗn độn DLL.

PS Như ông Fooz chỉ ra, điều quan trọng là phải nhất quán. Nếu bạn đang liên kết với các thư viện khác, bạn cần sử dụng cùng một tùy chọn họ làm. Nếu bạn đang sử dụng DLL của bên thứ ba, gần như chắc chắn rằng bạn sẽ cần sử dụng phiên bản DLL của thư viện thời gian chạy.


14

Tôi thích liên kết tĩnh với / MT.

Mặc dù bạn có một tệp thực thi nhỏ hơn với / MD, bạn vẫn phải gửi một loạt các DLL để đảm bảo người dùng có được phiên bản phù hợp để chạy chương trình của bạn. Và cuối cùng, trình cài đặt của bạn sẽ trở nên LỚN hơn khi liên kết với / MT.

Điều tồi tệ hơn nữa, nếu bạn chọn đưa các thư viện thời gian chạy của mình vào thư mục windows, sớm muộn người dùng sẽ cài đặt một ứng dụng mới với các thư viện khác nhau và, nếu gặp xui xẻo, sẽ phá vỡ ứng dụng của bạn.


5
Ý tưởng rất tệ là "đặt thư viện thời gian chạy của bạn vào thư mục windows". Bạn có thể phá vỡ các ứng dụng ngu ngốc khác đã làm tương tự trước khi bạn làm. Sử dụng SxS và để trình cài đặt xử lý nó hoặc gắn với / MT.
MSalters

1
Tôi hoàn toàn đồng ý rằng đó là một ý tưởng tồi. Một số người làm điều đó mặc dù, vì vậy tôi đã mô tả lý do tại sao đây không phải là một ý tưởng tốt.
Adrian Grigore

@AdrianGrigore tại sao một ứng dụng mới với các thư viện khác nhau sẽ gây ra sự cố trong ứng dụng của bạn? Nếu bạn sử dụng liên kết / MD, bạn sẽ bắt đầu tải các phiên bản mới của thư viện phải không?
rturrado

4
@rturrado: không hẳn. Cài đặt các ứng dụng khác trên đầu trang của bạn có thể ghi đè lên các dll của bạn với các phiên bản cũ hơn. Các phiên bản mới hơn sẽ biến mất. Điều này thường được gọi là "dll hell", xem en.wikipedia.org/wiki/DLL_Hell
Adrian Grigore

1
Microsoft đã từ bỏ WinSxS trong Visual Studio 2010 - các thư viện thời gian chạy hiện đang được triển khai riêng tư hoặc trong system32 ( msdn.microsoft.com/en-us/l Library / vstudio / dd293574.aspx ).
BCran

8

Vấn đề bạn sẽ gặp phải với / MD là phiên bản đích của CRT có thể không có trên máy người dùng của bạn (đặc biệt nếu bạn đang sử dụng phiên bản Visual Studio mới nhất và người dùng có hệ điều hành cũ hơn).

Trong trường hợp đó, bạn phải tìm ra cách lấy đúng phiên bản vào máy của họ.


7

từ http://msdn.microsoft.com/en-us/l Library / 2kzt1wy3 (VS.71) .aspx :

/ MT Xác định _MT để các phiên bản cụ thể đa luồng của các thói quen thời gian chạy được chọn từ các tệp tiêu đề (.h) tiêu chuẩn. Tùy chọn này cũng khiến trình biên dịch đặt tên thư viện LIBCMT.lib vào tệp .obj để trình liên kết sẽ sử dụng LIBCMT.lib để phân giải các ký hiệu bên ngoài. Hoặc / MT hoặc / MD (hoặc tương đương gỡ lỗi của chúng / MTd hoặc / MDd) là bắt buộc để tạo các chương trình đa luồng.

/ MD Xác định _MT và _DLL để cả hai phiên bản dành riêng cho đa luồng và DLL của các thói quen thời gian chạy được chọn từ các tệp .h tiêu chuẩn. Tùy chọn này cũng khiến trình biên dịch đặt tên thư viện MSVCRT.lib vào tệp .obj.

Các ứng dụng được biên dịch với tùy chọn này được liên kết tĩnh với MSVCRT.lib. Thư viện này cung cấp một lớp mã cho phép trình liên kết giải quyết các tham chiếu bên ngoài. Mã làm việc thực tế được chứa trong MSVCR71.DLL, mã này phải có sẵn trong thời gian chạy cho các ứng dụng được liên kết với MSVCRT.lib.

Khi / MD được sử dụng với _STATIC_CPPLIB được xác định (/ D_STATIC_CPPLIB), nó sẽ khiến ứng dụng liên kết với Thư viện C ++ đa luồng tĩnh (libcpmt.lib) thay vì phiên bản động (msvcprt.lib) trong khi vẫn liên kết động với CRT chính msvcrt.lib.

Vì vậy, nếu tôi diễn giải nó một cách chính xác thì / MT liên kết tĩnh và / MD liên kết động.


Câu hỏi là "tôi nên sử dụng cái nào?", Đây không phải là câu trả lời.
Leonard Inkret

1

Nếu bạn đang xây dựng tệp thực thi sử dụng tùy chọn dlls hoặc libs hơn / MD thì sẽ được ưu tiên hơn vì cách đó tất cả các thành phần sẽ được chia sẻ cùng một thư viện. Tất nhiên tùy chọn này phải phù hợp với tất cả các mô-đun liên quan, ví dụ như dll / lib / exe.

Nếu tệp thực thi của bạn không sử dụng bất kỳ lib hoặc dll nào hơn cuộc gọi của bất kỳ ai. Sự khác biệt bây giờ không quá nhiều vì khía cạnh chia sẻ không được chơi.

Vì vậy, có thể bạn có thể khởi động ứng dụng bằng / MT vì không có lý do thuyết phục nào khác nhưng khi đến lúc thêm lib hoặc dll, bạn có thể thay đổi nó thành / MD với lib / dll rất dễ dàng.

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.