/ MD veya / MT ile mi derlemeliyim?


127

Visual Studio'da, istediğiniz türden C çalışma zamanı kitaplığını seçmenize olanak tanıyan / MD ve / MT derleme bayrakları vardır.

Uygulamadaki farkı anlıyorum, ancak hangisini kullanacağımdan hala emin değilim. Artıları / eksileri nelerdir?

Duyduğum / MD'nin bir avantajı, birisinin çalışma zamanını güncellemesine izin vermesi (bir güvenlik sorununa yama gibi) ve uygulamamın bu güncellemeden yararlanacağıdır. Bana göre, bu neredeyse özelliksiz gibi görünüyor: İnsanların yeni sürüme karşı test etmeme izin vermeden çalışma zamanımı değiştirmelerini istemiyorum!

Merak ettiğim bazı şeyler:

  • Bu, derleme sürelerini nasıl etkiler? (muhtemelen / MT biraz daha yavaş?)
  • Diğer çıkarımlar neler?
  • Çoğu insan hangisini kullanıyor?

1
Daha fazla bilgi ve öneri şu adreste bulunabilir: stackoverflow.com/questions/787216
Weidenrinde

Yanıtlar:


87

/ MD ile dinamik olarak bağlantı kurarak,

  • sistem güncellemelerine maruz kalırsanız (iyi veya kötü),
  • yürütülebilir dosyanız daha küçük olabilir (içinde kitaplık bulunmadığından) ve
  • En azından bir DLL'nin kod segmentinin onu aktif olarak kullanan tüm süreçler arasında paylaşıldığına inanıyorum (tüketilen toplam RAM miktarını azaltır).

Ayrıca pratikte, farklı çalışma zamanı seçenekleriyle oluşturulmuş yalnızca statik bağlantılı 3. taraf ikili kitaplıklarla çalışırken, ana uygulamadaki / MT'nin / MD'den çok daha sık çakışmalara neden olma eğiliminde olduğunu buldum (çünkü C çalışma zamanı statik olarak birden çok kez bağlanırsa, özellikle farklı sürümlerse sorun yaşar.


11
Sistem güncelleme biti SxS tarafından biraz azaltılır. (- güvenlik güncellemeleri bu kararı bozması olabilir istekler değil alır) EXE CRT sürüm istediği bir açıklamadan alır
MSalters

1
Bu, MD kullanarak derleme yaparsam ve programım bir dll'ye bağımlıysa, bağımlılık dll'sinin olmadığı bir bilgisayarda çalışıyorsa programın başarısız olacağı anlamına mı geliyor?
gerrytan

5
@gerrytan: Evet, yazılımı çalıştırmak isteyen tüm bilgisayarlarda kullanılan uygun DLL'lerin bulunduğundan emin olmanız gerekir. Bunun tipik çözümleri, kullanıcının uygun MSVC yeniden dağıtılabilir paketini yüklemesini sağlamak veya tüm işi yapan bir yükleyici kullanmaktır.
Bay Fooz

@Royi Emin değilim, ancak /MTuygulamanızın her seferinde çalışma zamanı işlevinin uygulamasını aramasına gerek olmadığı için çalışma zamanında biraz daha hızlı olacağını düşünüyorum , bu düzeyde bir uzman değilim ama çoğu durumda eminim İşletim sistemleri çalışma zamanı uygulamalarını önbelleğe alacak, böylece uygulamanız önbelleğe alınmış sürümü kullanacak, bu yüzden fark o kadar uzak olmayacak, emin olmadığımdan bahsettiğime dikkat edin, bu yüzden bu yorumu argüman olarak almayın.
Ahmed Kamal

34

DLL kullanıyorsanız, dinamik olarak bağlantılı CRT (/ MD) için gitmelisiniz.

.Exe ve tüm .dll dosyalarınız için dinamik CRT kullanırsanız, hepsi tek bir CRT uygulamasını paylaşacaklardır - bu, hepsinin tek bir CRT yığınını paylaşacağı ve tek bir .exe / .dll'de ayrılmış belleğin serbest bırakılabileceği anlamına gelir. bir diğeri.

Statik CRT'yi .exe ve tüm .dll'leriniz için kullanırsanız, hepsi CRT'nin ayrı bir kopyasını alırlar - bu, hepsinin kendi CRT yığınlarını kullanacağı anlamına gelir, bu nedenle belleğin aynı modülde serbest bırakılması gerekir. tahsis edildi. Ayrıca, kod şişkinliği (CRT'nin birden fazla kopyası) ve aşırı çalışma süresi ek yükünden de muzdarip olacaksınız (her yığın, durumunu takip etmek için işletim sisteminden bellek ayırır ve ek yük fark edilebilir olabilir).


20

Visual Studio aracılığıyla oluşturulan projeler için varsayılanın / MD olduğuna inanıyorum.

/ MT kullanırsanız, yürütülebilir dosyanız hedef sistemde bulunan bir DLL'ye bağlı olmayacaktır. Bunu bir yükleyiciye sarıyorsanız, muhtemelen bir sorun olmayacak ve her iki şekilde de gidebilirsiniz.

/ MT'yi kendim kullanıyorum, böylece tüm DLL karmaşasını görmezden gelebilirim.

Not: Bay Fooz'un da işaret ettiği gibi, tutarlı olmak çok önemli. Diğer kitaplıklarla bağlantı kuruyorsanız, onların yaptıklarıyla aynı seçeneği kullanmanız gerekir. Üçüncü taraf bir DLL kullanıyorsanız, çalışma zamanı kitaplığının DLL sürümünü kullanmanız neredeyse kesindir.


14

Statik olarak / MT ile bağlamayı tercih ederim.

/ MD ile daha küçük bir yürütülebilir dosya edinmiş olsanız bile, kullanıcının programınızı çalıştırmak için doğru sürümü aldığından emin olmak için yine de bir dizi DLL göndermeniz gerekir. Ve sonunda yükleyiciniz / MT ile bağlantı kurarken olduğundan DAHA BÜYÜK olacaktır.

Daha da kötüsü, çalışma zamanı kitaplıklarınızı windows dizinine koymayı seçerseniz, er ya da geç kullanıcı farklı kitaplıklara sahip yeni bir uygulama yükleyecek ve herhangi bir kötü şansla uygulamanızı bozacaktır.


5
"Çalışma zamanı kitaplıklarınızı windows dizinine koymak" çok kötü bir fikir. Sizden önce aynı şeyi yapan diğer aptal uygulamaları kırabilirsiniz. SxS kullanın ve yükleyicinin onu işlemesine izin verin veya / MT ile devam edin.
MSalters

1
Bunun kötü bir fikir olduğuna tamamen katılıyorum. Yine de bazı insanlar yapıyor, bu yüzden bunun neden iyi bir fikir olmadığını açıklıyordum.
Adrian Grigore

@AdrianGrigore Neden farklı kitaplıklara sahip yeni bir uygulama uygulamanızda bir kesintiye neden olsun? / MD bağlantısını kullanırsanız, kitaplıkların yeni sürümlerini yüklemeye başlarsınız değil mi?
rturrado

4
@rturrado: pek değil. Sizinkinin üzerine başka uygulamalar yüklemek, eski sürümlerle dll'lerinizin üzerine yazabilir. Daha yeni sürümler gitmiş olacaktı. Bu genellikle "dll cehennemi" olarak bilinir, bkz. En.wikipedia.org/wiki/DLL_Hell
Adrian Grigore

1
Microsoft, Visual Studio 2010'da WinSxS'den vazgeçti - çalışma zamanı kitaplıkları artık ya özel olarak ya da system32'de ( msdn.microsoft.com/en-us/library/vstudio/dd293574.aspx ) dağıtılıyor .
BCran

8

/ MD ile karşılaşacağınız sorun, CRT'nin hedef sürümünün kullanıcı makinenizde olmamasıdır (özellikle Visual Studio'nun en son sürümünü kullanıyorsanız ve kullanıcının daha eski bir işletim sistemi varsa).

Bu durumda, makinelerine doğru sürümü nasıl yükleyeceğinizi bulmanız gerekir.


7

dan http://msdn.microsoft.com/en-us/library/2kzt1wy3(VS.71).aspx :

/ MT Çalışma zamanı yordamlarının çok iş parçacıklı özel sürümlerinin standart üstbilgi (.h) dosyalarından seçilmesi için _MT'yi tanımlar. Bu seçenek ayrıca derleyicinin LIBCMT.lib kitaplık adını .obj dosyasına yerleştirmesine neden olur, böylece bağlayıcının harici sembolleri çözümlemek için LIBCMT.lib kullanmasını sağlar. Çok iş parçacıklı programlar oluşturmak için / MT veya / MD (veya bunların hata ayıklama eşdeğerleri / MTd veya / MDd) gereklidir.

/ MD Çalışma zamanı rutinlerinin hem çok iş parçacıklı hem de DLL'ye özgü sürümlerinin standart .h dosyalarından seçilmesi için _MT ve _DLL'yi tanımlar. Bu seçenek, derleyicinin kitaplık adını MSVCRT.lib .obj dosyasına yerleştirmesine de neden olur.

Bu seçenekle derlenen uygulamalar statik olarak MSVCRT.lib ile bağlantılıdır. Bu kitaplık, bağlayıcının harici referansları çözümlemesine izin veren bir kod katmanı sağlar. Gerçek çalışma kodu MSVCR71.DLL içinde bulunur ve MSVCRT.lib ile bağlantılı uygulamalar için çalışma zamanında kullanılabilir olması gerekir.

/ MD, _STATIC_CPPLIB tanımlı (/ D_STATIC_CPPLIB) ile kullanıldığında, uygulamanın dinamik sürüm (msvcprt.lib) yerine statik çok iş parçacıklı Standart C ++ Kitaplığı (libcpmt.lib) ile bağlantı kurmasına neden olurken ana CRT ile dinamik olarak bağlantı kurmaya devam eder. msvcrt.lib.

Yani eğer doğru yorumluyorsam / MT statik olarak ve / MD dinamik olarak bağlanır.


Soru "hangisini kullanmalıyım?" İdi, bu bir cevap değil.
Leonard Inkret

2

Diğer dll'leri veya kitaplıkları kullanan bir yürütülebilir dosya oluşturuyorsanız / MD seçeneği tercih edilir çünkü bu şekilde tüm bileşenler aynı kitaplığı paylaşacaktır. Elbette bu seçenek, dll / lib / exe gibi ilgili tüm modüller için eşleşmelidir.

Çalıştırılabilir dosyanız, herhangi birinin çağrısı dışında herhangi bir lib veya dll kullanmıyorsa. Aradaki fark çok fazla değil çünkü paylaşım yönü oyuna girmiyor.

Öyleyse belki uygulamayı / MT ile başlatabilirsiniz, çünkü aksi halde zorlayıcı bir neden yoktur, ancak bir lib veya dll ekleme zamanı geldiğinde, bunu kolay olan lib / dll ile / MD olarak değiştirebilirsiniz.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.