Potential errors in passing CRT objects across DLL boundaries

Source: Internet
Author: User

Potential errors in passing CRT objects across DLL boundaries

Translation: Magictong (Tong Lei) May 2013

Copyright: Microsoft

Original address: http://msdn.microsoft.com/en-us/library/ms235460 (v=vs.80). aspx

Brief introduction

When you pass a C run-time (CRT) object (such as a file handle, locale, environment variable, and so on) to the outgoing DLL (by calling some of the functions exposed in the DLL), if the DLL loads a different CRT library than the executable, you may find something that is not intentional.

There is one that you may have encountered, similar to the problem that if the executable program allocates a piece of memory outside (shown by new or malloc allocations, or by calling Strdup,strstreambuf::str, etc., the implicit allocation of functions), The allocated memory pointer is then passed into the DLL by invoking the function exposed by the DLL, and if the DLL loads a different CRT library, it may cause memory access violation (AV) or heap corruption.

If you are debugging a program, this problem may print an error message in the Debug Output window as follows:

Heap[]: Invalid Address specified to Rtlvalidateheap (#,#)

Reason

Replicas of each CRT library have a separate and unique state, so CRT objects such as file handles, locales, and environment variables are only valid in the CRT library that allocates it or sets it. When a DLL and the program using this DLL are using two different CRT libraries, if you pass these CRT objects to each other on both the DLL and the program that uses the DLL, and you want the program to run normally, it is unlikely.

In addition, because each copy of the CRT library has its own heap manager, the allocation of memory in one CRT library (by invoking a function exposed by the DLL) to another CRT library may lead to heap corruption.

If you want to design a DLL that can pass the CRT object, or explicitly allocate memory inside the DLL, and release it outside the DLL, you must restrict the user of this DLL to use the same CRT library as the DLL. Instead, users of DLLs use the same CRT libraries as DLLs unless they are linked to the same version of the CRT dynamic-link library. If the application and DLL are compiled differently, for example, the application uses Visual c++5.0 compilation and the DLL uses Visual C + + 4.1 compilation or earlier, because the CRT libraries used by Visual C + + 4.1 are Msvcrt40.dll, and the visual c++5.0 is using Msvcrt.dll, which can be very cumbersome. You may not be able to recompile your application so that it is identical to the CRT library used by the DLL.

However, there is a special case. In some special versions of Windows NT 4.0 and Windows 2000 (for example, the American English version, Germany, France and the Czech Republic localized versions), a proxy mode of Msvcrt40.dll was used (the specific version is 4.20). In these environments, Although the DLL is linked to the Msvcrt40.dll,dll user (application) link is msvcrt.dll, but because all calls to Msvcrt40.dll are transferred to the Msvcrt.dll, this situation is still using the same CRT library.

However, this proxy version of Msvcrt40.dll in Windows 95,windows 98,windows me and some other localized Windows NT 4.0 and Windows 2000 (such as Japanese, Korean, and Chinese) versions are not valid. Therefore, if your application's target operating system is these environments, you need to obtain an upgraded version of the DLL that does not rely on Msvcrt40.dll, or change your application. If you have already developed this DLL, then recompile the DLL with Visual C + + 4.2 or later, if the DLL is a third-party provided component, you may need to provide an upgrade for the relevant developer.

Example One

Describe

Here is an instance of passing a file handle across a DLL boundary.

if DLL files and. exe files are compiled using/MD, then they use the same copy of the CRT library, which is fine.

If you use/MT to recompile so that they use a different CRT library and then run Test1Main.exe, an access violation (access violation) immediately occurs.

Code

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);

}

Code

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");

}

Output

This is a string

Example Two

Describe

This example illustrates the issue of passing environment variables across DLLs.

Code

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 have not been set.\n");

Free (Libvar);

}

Code

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 ();

}

If both the DLL and the. exe file are compiled using/MD, then both use the same copy of the CRT library, when the output is new Mylib variable is:c:\mylib;c:\yourlib, and if both are compiled with/MT, the output will be Mylib has not been set.

(Note: The above two instances, translator Magictong has not been tested, if there is a problem, please tell Magictong)

Reference documents

C Run-Time library http://msdn.microsoft.com/en-us/library/abx4dbyh (v=vs.100). aspx

http://blog.csdn.net/magictong/article/details/8927049

Potential errors in passing CRT objects across DLL boundaries

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.