Aracılığıyla paylaş


crt nesneleri dll sınırlarında ileterek olası hataları

c geçirdiğinizde çalıştırma (crt) dosya tanıtıcıları, yerel ayarlar ve ortam değişkenleri gibi içine veya dışına dll (işlev çağrıları) dll sınırı boyunca dll içinde arama dosyalarının yanı sıra, dll crt kitaplıklar farklı kopyalarını kullanıyorsanız, beklenmeyen davranış oluşabilir nesneleri.

Bellek ayrılamadı ilgili bir sorun oluşabilir (ya da açık olarak new veya malloc, veya örtülü olarak strdup, strstreambuf::str, vb.) ve ardından işaretçi boşaltılması için bir dll sınırından geçmesi. dll ve kullanıcıları crt kitaplıklar farklı kopyalarını kullanıyorsanız, bu bellek erişim ihlali veya yığın bozulmasına neden olabilir.

Bu sorunun başka bir belirtisi, output penceresinde hata gibi hata ayıklama sırasında şunlar olabilir:

YIĞIN []: RtlValidateHeap(#,#) için belirtilen geçersiz adres

Nedenler

crt kitaplığı her kopyasını ayrı ve farklı bir durumu vardır. Dolayısıyla, ortam değişkenleri gibi dosya tanıtıcıları crt nesne ve yerel ayarları yalnızca geçerli kopyasını crt bu nesnelerin nerede ayrılan veya ayarlamak için. dll ve kullanıcıları crt kitaplık farklı kopyalarını kullandığınızda, bu crt nesneleri dll sınırından geçmesi ve bunları diğer tarafına doğru alınmayı bekler.

Kendi yığın yöneticisinin her crt kitaplık kopyası olduğundan, ayrıca, bir crt Kitaplığı'nda Bellek ayırırken ve crt kitaplık farklı bir kopyasını boşaltılması için bir dll sınırı boyunca işaretçiyi geçirerek yığın bozulması için olası bir nedeni var.

crt nesneleri sınırından geçirir veya bellek ayırır ve dll dışında boşaltılması bekler, dll dosyanızın tasarlarsanız, dll kullanıcıların dll crt kitaplığı aynı kopyasını kısıtlayın. Yalnızca her ikisi de aynı crt dll sürümü ile bağlantılıdır, dll ve kullanıcıları aynı kopyasını crt kitaplığı kullanın. Visual C++ 4.1 veya daha önceki sürümlerde oluşturulmuş DLL'lerle birlikte Visual C++ 5.0 ile oluşturulan uygulamalar karıştırırsanız, bu bir sorun olabilir. Visual C++ 4.1 tarafından kullanılan crt kitaplığı dll sürümü msvcrt40.dll ve görsel 5.0 tarafından kullanılan msvcrt.dll olduğundan bu DLL'ler crt kitaplığı aynı kopyasını kullanmak için uygulama oluşturamıyor.

Ancak, bir özel durum söz konusudur. Almanca, Fransızca ve Çekçe, bir iletici sürümünü (sürüm 4.20) msvcrt40.dll sevk edildiğinde gibi ABD İngilizcesinde sürüm ve bazı diğer Windows 2000 sürümlerinde yerelleştirilmiş. Msvcrt40.dll için yapılan tüm aramalar için msvcrt.dll iletildiği çünkü Sonuçta, dll ile msvcrt40.dll bağlı olduğu ve kendi kullanıcı msvcrt.dll ile bağlantılı olduğu halde crt kitaplığı aynı kopyasını kullanmaya devam.

Ancak bu msvcrt40.dll iletici sürümü Windows 2000, Japonca, Korece ve Çince gibi bazı yerelleştirilmiş sürümlerinde kullanılabilir değildir. Uygulamanız bu işletim sistemlerinde hedefler, bu nedenle ya da olmayan veya üzerinde msvcrt40.dll dayanan uygulamanız crt kitaplıkları aynı kopyasını kullanarak yararlanmayı değil alter dll yükseltilmiş sürümünü almanız. dll geliştirdiyseniz, bu Visual C++ 4.2 veya daha sonra yeniden inşa etmek anlamına gelir. Üçüncü şahıs bir dll ise, yükseltme için satıcınıza başvurmanız gerekir.

Msvcrt40.dll (sürüm 4.20) bu ileticiyi dll sürümünü yeniden dağıtılıyor olamaz unutmayın.

Örnek

ms235460.collapse_all(tr-tr,VS.110).gifDescription

Bu örnek bir dosya işleyici dll sınırı boyunca geçirir.

dll ve .exe dosyası yerleşik /md ile crt tek bir kopyasını paylaşmasını.

Böylece crt ayrı kopyalarını kullandıkları /mt ile yeniden oluşturursanız, elde edilen sonuçları test1Main.exe dosyasında erişim ihlali çalışıyor.

ms235460.collapse_all(tr-tr,VS.110).gifKod

// test1Dll.cpp
// compile with: /MD /LD
#include <stdio.h>
__declspec(dllexport) void writeFile(FILE *stream)
{
   char   s[] = "this is a string\n";
   fprintf( stream, "%s", s );
   fclose( stream );
}

ms235460.collapse_all(tr-tr,VS.110).gifKod

// test1Main.cpp
// compile with: /MD test1dll.lib
#include <stdio.h>
#include <process.h>
void writeFile(FILE *stream);

int main(void)
{
   FILE  * stream;
   errno_t err = fopen_s( &stream, "fprintf.out", "w" );
   writeFile(stream);
   system( "type fprintf.out" );
}

ms235460.collapse_all(tr-tr,VS.110).gifÇıktı

this is a string

Örnek

ms235460.collapse_all(tr-tr,VS.110).gifDescription

Bu örnek, bir dll sınırından ortam değişkenlerini geçirir.

ms235460.collapse_all(tr-tr,VS.110).gifKod

// test2Dll.cpp
// compile with: /MT /LD
#include <stdio.h>
#include <stdlib.h>

__declspec(dllexport) void readEnv()
{
   char *libvar;
   size_t libvarsize;

   /* Get the value of the MYLIB environment variable. */ 
   _dupenv_s( &libvar, &libvarsize, "MYLIB" );

   if( libvar != NULL )
      printf( "New MYLIB variable is: %s\n", libvar);
   else
      printf( "MYLIB has not been set.\n");
   free( libvar );
}

ms235460.collapse_all(tr-tr,VS.110).gifKod

// test2Main.cpp
// compile with: /MT /link test2dll.lib
#include <stdlib.h>
#include <stdio.h>

void readEnv();

int main( void )
{
   _putenv( "MYLIB=c:\\mylib;c:\\yourlib" );
   readEnv();
}

ms235460.collapse_all(tr-tr,VS.110).gifÇıktı

MYLIB has not been set.

crt yalnızca bir kopyasını kullanılmasını sağlamak amacıyla dll ve .exe dosyası ile /md yerleşiktir, programın başarılı bir şekilde çalışır ve aşağıdaki çıktıyı üretir:

New MYLIB variable is: c:\mylib;c:\yourlib

Ayrıca bkz.

Başvuru

crt kitaplığı özellikleri