2013-03-02 16 views
6

arası geçiş yapılamıyor Visual Studio 2010'da, bir birim MFC DLL karşı birim sınamaları yazmak için bir proje oluşturdum. Tek başlık birimi sınama çerçevesi kullanıyorum ve birim sınama projesinden MFC DLL's lib wrapper'a bağlıyım. Kurucusunda std::wstring alan bir sınıf oluşturmaya çalışıyorum.Std :: wstring DLL

Foobar
TEST_CASE("MyProject/MyTest", "Do the test.") 
{ 
    MockDbService mockDbService; 
    Foobar foo(L"{F00DFACE-FEED-DEAD-BEEF-C0FFEEDECADE}", mockDbService); 

    foo.loadObject(); 

    REQUIRE(mockDbService.getMethodInvokeCount("query()") >= 1); 
} 

test altında MFC DLL ihraç sınıftır: İşte benim test böyle görünüyor. Ancak, test çerçevesi beklenmedik bir istisna bildiriyor. Dizeyi Foobar yapıcısına kopyalarken std::wstring'un kopya yapıcısını izledim. MSVC hata ayıklayıcı, kaynak dizeyi <Bad Ptr> olarak bildirir.

Bir dummy oluşturucu, Foobar::Foobar(long num, IDbService& db) oluşturdum ve tüm değerler (IDbService& dahil) gayet iyi bir şekilde karşımıza çıkıyor.

Hem MFC DLL hem de birim sınama EXE, derleyici bayraklarını eşdeğer tutması gereken bir özellik sayfası paylaşıyor. Testi hata ayıklama modunda yapıyorum ve çalıştırıyorum. std::wstring neden DLL'de kopyalanamaz herhangi bir fikir?

+2

Hem EXE'yi hem de DLL'yi CRT'nin hata ayıklama sürümü ile dinamik olarak bağlıyor musunuz? ('/ MDd') –

+1

@ Mr.C64 Vay, işte buydu. Ünite test projemde '/ MD' kullanıldı ve MFC DLL'/MDd' idi. Bir cevap olarak kısa bir açıklama yapmayı çok isterim; ve kabul edeceğim. Teşekkürler! –

+0

Kısa bir açıklama ekledim. Temel olarak, sizin durumunuzdaki sorunun debug-build'in std :: wstring'inin sürüm-build'in std :: wstring'den farklı bir uygulaması olduğunu düşünüyorum. –

cevap

9

Sen EXE ve DLL hem olup olmadığını kontrol etmelidir dinamik aynı hata ayıklama CRT (/MDd derleyici seçeneği) ile bağladı. Ayrıca, _HAS_ITERATOR_DEBUGGING gibi diğer ayarların da EXE ve DLL için aynı olduğundan emin olun.

(kısayol sadece sınıf ara yüzeyde const wchar_t* yerine std::wstring kullanımı ve sadece şantiye vücut içinde ham tanıtıcısından bir std::wstring oluşturmak için olabilir).

DÜZENLEME: Sen CRT uyuşmazlığı (yani EXE /MDd ile inşa DLL vs /MD ile inşa edilmiş) doğruladı sorun oldu. Gerçek şu ki, std::wstring aynı sınıf adı, hata ayıklama yapılarında (/MDd) iki farklı sınıf anlamına gelir ve sürümde (/MD) oluşturur. Aslında, hata ayıklamada, hata ayıklamaya yardımcı olmak için sınıf uygulamasında ek mekanikler olabilir; Bu mekanikler verimsizlikler ortaya çıkarabilir, bu yüzden serbest bırakma yapılarında çıkarılır. Bu nedenle, hata ayıklama yapısının std::wstring iç yapısı, sürüm oluşturucunun std::wstring'dan farklıdır (ör. öğesinin std::wstring örneklerini yazdırmaya çalışırsanız, sürümlerde farklı numaralar oluşturur ve hata ayıklar oluşturur). Yani, /MD ile oluşturulan EXE, sürüm oluşturma sürümünün std::wstring; bunun yerine /MDd ile oluşturulan DLL, debug-build'in std::wstring olmasını bekliyordu: bu iki beklenti arasında bir uyumsuzluk var (bir modül X sınıfını bekliyor ancak diğer modül Y sınıfını veriyor) ve böylece bir çökmeniz var.

+0

Bu mantıklı. Teşekkür ederim. Bu durumda, benim sorunum tam olarak daha önce bulduğum şey: http://stackoverflow.com/questions/2322095/why-does-this-program-crash-passing-of-stdstring-between-dlls?rq=1 Ama Her iki projem de Debug'da oluşturuldu, dolayısıyla bunun alakalı olduğunu düşünmedim. Söylediklerinize göre, hata ayıklama projeleriyle bile CRT'nin sürüm oluşturmasını kullanıyordum. Tekrar teşekkürler. –

+1

Evet, '/ MD', CRT DLL'yi serbest bırakmak için dinamik bağlantı oluşturuyor; '/ MDd' CRT DLL hata ayıklamak için dinamik bağlantı. –

İlgili konular