Π§ΠΈΡ‚Π°ΠΉΡ‚Π΅ ΠΊΠ½ΠΈΠ³ΠΈ ΠΎΠ½Π»Π°ΠΉΠ½ Π½Π° Bookidrom.ru! БСсплатныС ΠΊΠ½ΠΈΠ³ΠΈ Π² ΠΎΠ΄Π½ΠΎΠΌ ΠΊΠ»ΠΈΠΊΠ΅

Π§ΠΈΡ‚Π°Ρ‚ΡŒ ΠΎΠ½Π»Π°ΠΉΠ½ «БистСмноС ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠΈΡ€ΠΎΠ²Π°Π½ΠΈΠ΅ Π² срСдС WindowsΒ». Π‘Ρ‚Ρ€Π°Π½ΠΈΡ†Π° 101

Автор ДТонсон Π₯Π°Ρ€Ρ‚

Ѐункция DllMain слуТит Ρ…Π°Ρ€Π°ΠΊΡ‚Π΅Ρ€Π½Ρ‹ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ΠΎΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΡ ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π΄ΠΎΠ»Π³ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Ρ… состояний Π² ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСдС ΠΈ ΠΎΠ±ΡŠΠ΅Π΄ΠΈΠ½ΡΠ΅Ρ‚ TLS ΠΈ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ DLL.

ΠžΡΠ²ΠΎΠ±ΠΎΠΆΠ΄Π°Ρ‚ΡŒ рСсурсы ΠΏΡ€ΠΈ отсоСдинСнии ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² (случай DLL_THREAD_DETACH) особСнно Π²Π°ΠΆΠ½ΠΎ Π² случаС сСрвСрной срСды; Ссли этого Π½Π΅ Π΄Π΅Π»Π°Ρ‚ΡŒ, Ρ‚ΠΎ рСсурсы сСрвСра, Π² ΠΊΠΎΠ½Π΅Ρ‡Π½ΠΎΠΌ счСтС, ΠΈΡΡ‡Π΅Ρ€ΠΏΠ°ΡŽΡ‚ΡΡ, Ρ‡Ρ‚ΠΎ ΠΌΠΎΠΆΠ΅Ρ‚ привСсти ΠΊ сбоям Π² Π΅Π³ΠΎ Ρ€Π°Π±ΠΎΡ‚Π΅ ΠΈΠ»ΠΈ сниТСнию ΠΏΡ€ΠΎΠΈΠ·Π²ΠΎΠ΄ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ ΠΈΠ»ΠΈ ΠΊ Ρ‚ΠΎΠΌΡƒ ΠΈ Π΄Ρ€ΡƒΠ³ΠΎΠΌΡƒ ΠΎΠ΄Π½ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½ΠΎ.

ΠŸΡ€ΠΈΠΌΠ΅Ρ‡Π°Π½ΠΈΠ΅

НСкоторыС ΠΈΠ· ΠΈΠ»Π»ΡŽΡΡ‚Ρ€ΠΈΡ€ΡƒΠ΅ΠΌΡ‹Ρ… Π½ΠΈΠΆΠ΅ ΠΊΠΎΠ½Ρ†Π΅ΠΏΡ†ΠΈΠΉ прямого ΠΎΡ‚Π½ΠΎΡˆΠ΅Π½ΠΈΡ ΠΊ сокСтам Π½Π΅ ΠΈΠΌΠ΅ΡŽΡ‚, Π½ΠΎ, Ρ‚Π΅ΠΌ Π½Π΅ ΠΌΠ΅Π½Π΅Π΅, Ρ€Π°ΡΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°ΡŽΡ‚ΡΡ ΠΈΠΌΠ΅Π½Π½ΠΎ здСсь, Π° Π½Π΅ Π² ΠΏΡ€Π΅Π΄Ρ‹Π΄ΡƒΡ‰ΠΈΡ… Π³Π»Π°Π²Π°Ρ…, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π΄Π°Π½Π½Ρ‹ΠΉ ΠΏΡ€ΠΈΠΌΠ΅Ρ€ прСдоставляСт ΡƒΠ΄ΠΎΠ±Π½ΡƒΡŽ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½ΠΎΡΡ‚ΡŒ для ΠΈΠ»Π»ΡŽΡΡ‚Ρ€Π°Ρ†ΠΈΠΈ ΠΌΠ΅Ρ‚ΠΎΠ΄ΠΎΠ² создания бСзопасных ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½Ρ‹Ρ… DLL Π² рСалистичСских условиях.

Π˜ΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‰ΠΈΠ΅ эту DLL ΠΊΠΎΠ΄Ρ‹ ΠΊΠ»ΠΈΠ΅Π½Ρ‚Π° ΠΈ сСрвСра, Π½Π΅Π·Π½Π°Ρ‡ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ ΠΈΠ·ΠΌΠ΅Π½Π΅Π½Π½Ρ‹Π΅ ΠΏΠΎ ΡΡ€Π°Π²Π½Π΅Π½ΠΈΡŽ с ΠΏΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ°ΠΌΠΈ 12.1 ΠΈ 12.2, доступны Π½Π° Web-сайтС ΠΊΠ½ΠΈΠ³ΠΈ.

ΠŸΡ€ΠΎΠ³Ρ€Π°ΠΌΠΌΠ° 12.4. SendReceiveSKST: бСзопасная многопоточная DLL 

/* SendReceiveSKST.с β€” DLL ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ²ΠΎΠ³ΠΎ сокСта. */

/* Π’ качСствС Ρ€Π°Π·Π΄Π΅Π»ΠΈΡ‚Π΅Π»Π΅ΠΉ сообщСний ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ символы ΠΊΠΎΠ½Ρ†Π° */

/* строки ('\0'), Ρ‚Π°ΠΊ Ρ‡Ρ‚ΠΎ Ρ€Π°Π·ΠΌΠ΅Ρ€ сообщСния Π·Π°Ρ€Π°Π½Π΅Π΅ Π½Π΅ извСстСн. */

/* ΠŸΠΎΡΡ‚ΡƒΠΏΠ°ΡŽΡ‰ΠΈΠ΅ Π΄Π°Π½Π½Ρ‹Π΅ Π±ΡƒΡ„Π΅Ρ€ΠΈΠ·ΡƒΡŽΡ‚ΡΡ ΠΈ ΡΠΎΡ…Ρ€Π°Π½ΡΡŽΡ‚ΡΡ Π² ΠΏΡ€ΠΎΠΌΠ΅ΠΆΡƒΡ‚ΠΊΠ°Ρ… ΠΌΠ΅ΠΆΠ΄Ρƒ */

/* Π²Ρ‹Π·ΠΎΠ²Π°ΠΌΠΈ Ρ„ΡƒΠ½ΠΊΡ†ΠΈΠΉ. */

/* Для этой Ρ†Π΅Π»ΠΈ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΡƒΡŽΡ‚ΡΡ Π»ΠΎΠΊΠ°Π»ΡŒΠ½Ρ‹Π΅ области хранСния ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

/* (Thread Local Storage, TLS), ΠΎΠ±Π΅ΡΠΏΠ΅Ρ‡ΠΈΠ²Π°ΡŽΡ‰ΠΈΠ΅ ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΈΠ· ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² */

/* собствСнным Π·Π°ΠΊΡ€Ρ‹Ρ‚Ρ‹ΠΌ "статичСским Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ΠΌ". */


#define _NOEXCLUSIONS

#include "EvryThng.h"

#include "ClntSrvr.h" /* ΠžΠΏΡ€Π΅Π΄Π΅Π»ΡΠ΅Ρ‚ записи запроса ΠΈ ΠΎΡ‚Π²Π΅Ρ‚Π°. */


typedef struct STATIC_BUF_T {

 /* "static_buf" содСрТит "static_buf_len" Π±Π°ΠΉΡ‚ΠΎΠ² остаточных Π΄Π°Π½Π½Ρ‹Ρ…. */

 /* Π‘ΠΈΠΌΠ²ΠΎΠ»Ρ‹ ΠΊΠΎΠ½Ρ†Π° строки (Π½ΡƒΠ»Π΅Π²Ρ‹Π΅ символы) ΠΌΠΎΠ³ΡƒΡ‚ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ, Π° ΠΌΠΎΠ³ΡƒΡ‚ */

 /* ΠΈ Π½Π΅ ΠΏΡ€ΠΈΡΡƒΡ‚ΡΡ‚Π²ΠΎΠ²Π°Ρ‚ΡŒ. */

 char static_buf[MAX_RQRS_LEN] ;

 LONG32 static_buf_len;

} STATIC_BUF;


static DWORD TlsIx = 0; /* ИндСкс TLS – Π”Π›Π― ΠšΠΠ–Π”ΠžΠ“Πž ΠŸΠ ΠžΠ¦Π•Π‘Π‘Π Π‘Π’ΠžΠ™ Π˜ΠΠ”Π•ΠšΠ‘.*/

 /* Для ΠΎΠ΄Π½ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ использовались Π±Ρ‹ ΡΠ»Π΅Π΄ΡƒΡŽΡ‰ΠΈΠ΅ опрСдСлСния:

  static char static_buf [MAX_RQRS_LEN];

  static LONG32 static_buf_len; */

 /* Основная функция DLL. */


BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {

 STATIC_BUF * pBuf;

 switch (fdwReason) {

 case DLL_PROCESS_ATTACH:

  TlsIx = TlsAlloc(); 

  /* Для основного ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ отсутствуСт, поэтому Π²ΠΎ врСмя ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡ процСсса Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ Π²Ρ‹ΠΏΠΎΠ»Π½ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ ΠΎΠΏΠ΅Ρ€Π°Ρ†ΠΈΠΈ ΠΏΠΎ ΠΏΠΎΠ΄ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΡŽ ΠΏΠΎΡ‚ΠΎΠΊΠ°. */

 case DLL_THREAD_ATTACH:

  /* Π£ΠΊΠ°Π·Π°Ρ‚ΡŒ, Ρ‡Ρ‚ΠΎ ΠΏΠ°ΠΌΡΡ‚ΡŒ Π½Π΅ Π±Ρ‹Π»Π° распрСдСлСна. */

  TlsSetValue(TlsIx, NULL);

  return TRUE; /* Π’ Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎΡΡ‚ΠΈ это Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ игнорируСтся. */

 case DLL_PROCESS_DETACH:

  /* ΠžΡ‚ΡΠΎΠ΅Π΄ΠΈΠ½ΠΈΡ‚ΡŒ Ρ‚Π°ΠΊΠΆΠ΅ основной ΠΏΠΎΡ‚ΠΎΠΊ. */

  pBuf = TlsGetValue(TlsIx);

  if (pBuf != NULL) {

   free(pBuf);

   pBuf = NULL;

  }

  return TRUE;

 case DLL_THREAD_DETACH:

  pBuf = TlsGetValue(TlsIx);

  if (pBuf != NULL) {

   free(pBuf);

   pBuf = NULL;

  }

  return TRUE;

 }

}


_declspec(dllexport) 

BOOL ReceiveCSMessage(REQUEST *pRequest, SOCKET sd) {

 /* Π’ΠΎΠ·Π²Ρ€Π°Ρ‰Π°Π΅ΠΌΠΎΠ΅ Π·Π½Π°Ρ‡Π΅Π½ΠΈΠ΅ TRUE ΡƒΠΊΠ°Π·Ρ‹Π²Π°Π΅Ρ‚ Π½Π° ΠΎΡˆΠΈΠ±ΠΊΡƒ ΠΈΠ»ΠΈ отсоСдинСниС. */

 BOOL Disconnect = FALSE;

 LONG32 nRemainRecv = 0, nXfer, k; /* Π”ΠΎΠ»ΠΆΠ½Ρ‹ Π±Ρ‹Ρ‚ΡŒ Ρ†Π΅Π»Ρ‹ΠΌΠΈ со Π·Π½Π°ΠΊΠΎΠΌ. */

 LPSTR pBuffer, message;

 CHAR TempBuf[MAX_RQRS_LEN + 1];

 STATIC_BUF *p;

 p = (STATIC_BUF *)TlsGetValue(TlsIx);

 if (p == NULL) { /* Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·Π°Ρ†ΠΈΡ ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Π²Ρ‹Π·ΠΎΠ²Π΅. */

  /* Π Π°ΡΠΏΡ€Π΅Π΄Π΅Π»ΡΡ‚ΡŒ это Ρ…Ρ€Π°Π½ΠΈΠ»ΠΈΡ‰Π΅ Π±ΡƒΠ΄ΡƒΡ‚ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ ΠΏΠΎΡ‚ΠΎΠΊΠΈ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΎΠ½ΠΎ */

  /* Π½Π΅ΠΎΠ±Ρ…ΠΎΠ΄ΠΈΠΌΠΎ. Π”Ρ€ΡƒΠ³ΠΈΠ΅ Ρ‚ΠΈΠΏΡ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΌΠΎΠ³ΡƒΡ‚ ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒ TLS для ΠΈΠ½Ρ‹Ρ… Ρ†Π΅Π»Π΅ΠΉ. */

  Ρ€ = malloc(sizeof(STATIC_BUF));

  TlsSetValue(TlsIx, p);

  if (p == NULL) return TRUE; /* Ошибка. */

  p->static_buf_len = 0; /* Π˜Π½ΠΈΡ†ΠΈΠ°Π»ΠΈΠ·ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ состояниС. */

 }

 message = pRequest->Record;

 /* Π‘Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ Π΄ΠΎ символа Π½ΠΎΠ²ΠΎΠΉ строки, оставляя остаточныС Π΄Π°Π½Π½Ρ‹Π΅ Π² статичСском Π±ΡƒΡ„Π΅Ρ€Π΅. */

 for (k = 0; k < p->static_buf_len && p->static_buf[k] != '\0'; k++) { 

  message[k] = p->static_buf[k];

 } /* k – количСство ΠΏΠ΅Ρ€Π΅Π΄Π°Π½Π½Ρ‹Ρ… символов. */

 if (k < p->static_buf_len) { /* Π’ статичСском Π±ΡƒΡ„Π΅Ρ€Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ Π½ΡƒΠ»Π΅Π²ΠΎΠΉ символ. */

  message[k] = '\0';

  p->static_buf_len –= (k + 1); /* Π‘ΠΊΠΎΡ€Ρ€Π΅ΠΊΡ‚ΠΈΡ€ΠΎΠ²Π°Ρ‚ΡŒ состояниС статичСского Π±ΡƒΡ„Π΅Ρ€Π°. */

  memcpy(p->static_buf, &(p->static_buf[k + 1]), p->static_buf_len);

  return FALSE; /* Π’Ρ…ΠΎΠ΄Π½Ρ‹Π΅ Π΄Π°Π½Π½Ρ‹Π΅ сокСта Π½Π΅ Ρ‚Ρ€Π΅Π±ΡƒΡŽΡ‚ΡΡ. */

 }


 /* ΠŸΠ΅Ρ€Π΅Π΄Π°Π½ вСсь статичСский Π±ΡƒΡ„Π΅Ρ€. ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° строки Π½Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½.*/

 nRemainRecv = sizeof(TempBuf) – 1 – p->static_buf_len;

 pBuffer = message + p->static_buf_len;

 p->static_buf_len = 0;

 while (nRemainRecv > 0 && !Disconnect) {

  nXfer = recv(sd, TempBuf, nRemainRecv, 0);

  if (nXfer <= 0) {

   Disconnect = TRUE;

   continue;

  }

  nRemainRecv –= nXfer;

  /* ΠŸΠ΅Ρ€Π΅Π΄Π°Ρ‚ΡŒ Π² Ρ†Π΅Π»Π΅Π²ΠΎΠ΅ сообщСниС всС символы Π²ΠΏΠ»ΠΎΡ‚ΡŒ Π΄ΠΎ Π½ΡƒΠ»Π΅Π²ΠΎΠ³ΠΎ, Ссли Ρ‚Π°ΠΊΠΎΠ²ΠΎΠΉ имССтся. */

  for (k =0; k < nXfer && TempBuf[k] != '\0'; k++) {

   *pBuffer = TempBuf[k];

   pBuffer++;

  }

  if (k >= nXfer) { /*ΠŸΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° строки Π½Π΅ ΠΎΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½, Ρ‡ΠΈΡ‚Π°Ρ‚ΡŒ дальшС*/

   nRemainRecv –= nXfer;

  } else { /* ΠžΠ±Π½Π°Ρ€ΡƒΠΆΠ΅Π½ ΠΏΡ€ΠΈΠ·Π½Π°ΠΊ ΠΊΠΎΠ½Ρ†Π° строки. */

   *pBuffer = '\0';

   nRemainRecv = 0;

   memcpy(p->static_buf, &TempBuf[k + 1], nXfer – k – 1);

   p->static_buf_len = nXfer – k – 1;

  }

 }

 return Disconnect;

}


_declspec(dllexport)

BOOL SendCSMessage(RESPONSE *pResponse, SOCKET sd) {

 /* ΠŸΠΎΡΠ»Π°Ρ‚ΡŒ запрос сСрвСру Π² сокСт sd. */

 BOOL Disconnect = FALSE;

 LONG32 nRemainSend, nXfer;

 LPSTR pBuffer; 

 pBuffer = pResponse->Record;

 nRemainSend = strlen(pBuffer) + 1;

 while (nRemainSend > 0 && !Disconnect) {

  /* ΠžΡ‚ΠΏΡ€Π°Π²ΠΊΠ° Π΅Ρ‰Π΅ Π½Π΅ Π³Π°Ρ€Π°Π½Ρ‚ΠΈΡ€ΡƒΠ΅Ρ‚, Ρ‡Ρ‚ΠΎ Π±ΡƒΠ΄Π΅Ρ‚ отослано всС сообщСниС. */

  nXfer = send(sd, pBuffer, nRemainSend, 0);

  if (nXfer <= 0) {

   fprintf(stderr, "\nΠžΡ‚ΠΊΠ»ΡŽΡ‡Π΅Π½ΠΈΠ΅ сСрвСра Π΄ΠΎ посылки запроса Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΡ");

   Disconnect = TRUE;

  }

  nRemainSend –=nXfer;

  pBuffer += nXfer;

 }

 return Disconnect;

ΠšΠΎΠΌΠΌΠ΅Π½Ρ‚Π°Ρ€ΠΈΠΈ ΠΏΠΎ ΠΏΠΎΠ²ΠΎΠ΄Ρƒ DLL ΠΈ бСзопасной ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ срСды

β€’ Π’сякий Ρ€Π°Π·, ΠΊΠΎΠ³Π΄Π° создаСтся Π½ΠΎΠ²Ρ‹ΠΉ ΠΏΠΎΡ‚ΠΎΠΊ, вызываСтся функция DllMain с ΠΎΠΏΡ†ΠΈΠ΅ΠΉ DLL_THREAD_ATTACH, Π½ΠΎ для основного ΠΏΠΎΡ‚ΠΎΠΊΠ° ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½ΠΎΠ³ΠΎ Π²Ρ‹Π·ΠΎΠ²Π° с ΠΎΠΏΡ†ΠΈΠ΅ΠΉ DLL_THREAD_ATTACH Π½Π΅ сущСствуСт. Π’ случаС основного ΠΏΠΎΡ‚ΠΎΠΊΠ° Π΄ΠΎΠ»ΠΆΠ½Π° ΠΈΡΠΏΠΎΠ»ΡŒΠ·ΠΎΠ²Π°Ρ‚ΡŒΡΡ опция DLL_PROCESS_ATTACH.

β€’ Π’ΠΎΠΎΠ±Ρ‰Π΅ говоря, Π² Ρ‚ΠΎΠΌ числС ΠΈ Π² Π΄Π°Π½Π½ΠΎΠΌ случаС (Π²ΠΎΠ·ΡŒΠΌΠΈΡ‚Π΅, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€, ΠΏΠΎΡ‚ΠΎΠΊ, ΠΏΡ€ΠΈΠ½ΠΈΠΌΠ°ΡŽΡ‰ΠΈΠΉ сообщСния (accept thread)), Π½Π΅ΠΊΠΎΡ‚ΠΎΡ€Ρ‹ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ распрСдСлСниС памяти ΠΌΠΎΠΆΠ΅Ρ‚ ΠΈ Π½Π΅ Ρ‚Ρ€Π΅Π±ΠΎΠ²Π°Ρ‚ΡŒΡΡ, Π½ΠΎ DllMain Π½Π΅ Π² состоянии Ρ€Π°Π·Π»ΠΈΡ‡Π°Ρ‚ΡŒ ΠΎΡ‚Π΄Π΅Π»ΡŒΠ½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ². ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ Π½Π° участкС ΠΊΠΎΠ΄Π°, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰Π΅ΠΌ Π²Π°Ρ€ΠΈΠ°Π½Ρ‚Ρƒ Π²Ρ‹Π±ΠΎΡ€Π° DLL_THREAD_ATTACH, фактичСского распрСдСлСния памяти Π½Π΅ происходит; здСсь Ρ‚ΠΎΠ»ΡŒΠΊΠΎ инициализируСтся ΠΏΠ°Ρ€Π°ΠΌΠ΅Ρ‚Ρ€ TLS. РаспрСдСлСниС памяти осущСствляСтся Ρ‚ΠΎΡ‡ΠΊΠΎΠΉ Π²Ρ…ΠΎΠ΄Π° ReceiveCSMessage ΠΏΡ€ΠΈ ΠΏΠ΅Ρ€Π²ΠΎΠΌ Π΅Π΅ Π²Ρ‹Π·ΠΎΠ²Π΅. Благодаря этому собствСнная ΠΏΠ°ΠΌΡΡ‚ΡŒ выдСляСтся Ρ‚ΠΎΠ»ΡŒΠΊΠΎ Ρ‚Π΅ΠΌ ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌ, ΠΊΠΎΡ‚ΠΎΡ€Ρ‹Π΅ Π² этом Π΄Π΅ΠΉΡΡ‚Π²ΠΈΡ‚Π΅Π»ΡŒΠ½ΠΎ Π½ΡƒΠΆΠ΄Π°ΡŽΡ‚ΡΡ, ΠΈ Ρ€Π°Π·Π»ΠΈΡ‡Π½Ρ‹Π΅ Ρ‚ΠΈΠΏΡ‹ ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² ΠΏΠΎΠ»ΡƒΡ‡Π°ΡŽΡ‚ Ρ€ΠΎΠ²Π½ΠΎ ΡΡ‚ΠΎΠ»ΡŒΠΊΠΎ рСсурсов, сколько ΠΈΠΌ трСбуСтся.

β€’ Π₯отя рассматриваСмая Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠ° DLL ΠΈ обСспСчиваСт Π±Π΅Π·ΠΎΠΏΠ°ΡΠ½ΡƒΡŽ ΠΌΠ½ΠΎΠ³ΠΎΠΏΠΎΡ‚ΠΎΡ‡Π½ΡƒΡŽ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΡƒ, любой ΠΏΠΎΡ‚ΠΎΠΊ Π² ΠΊΠ°ΠΆΠ΄Ρ‹ΠΉ ΠΌΠΎΠΌΠ΅Π½Ρ‚ Π²Ρ€Π΅ΠΌΠ΅Π½ΠΈ ΠΌΠΎΠΆΠ΅Ρ‚ Ρ€Π°Π±ΠΎΡ‚Π°Ρ‚ΡŒ Ρ‚ΠΎΠ»ΡŒΠΊΠΎ с ΠΎΠ΄Π½ΠΈΠΌ сокСтом, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ Π΄ΠΎΠ»Π³ΠΎΠ²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ состояния Π°ΡΡΠΎΡ†ΠΈΠΈΡ€ΡƒΡŽΡ‚ΡΡ Π½Π΅ с сокСтами, Π° с ΠΏΠΎΡ‚ΠΎΠΊΠ°ΠΌΠΈ. Π­Ρ‚ΠΎΡ‚ ΠΌΠΎΠΌΠ΅Π½Ρ‚ учитываСтся Π² ΡΠ»Π΅Π΄ΡƒΡŽΡ‰Π΅ΠΌ ΠΏΡ€ΠΈΠΌΠ΅Ρ€Π΅.

β€’ Π˜ΡΡ…ΠΎΠ΄Π½Ρ‹ΠΌ ΠΊΠΎΠ΄ΠΎΠΌ DLL, Ρ€Π°Π·ΠΌΠ΅Ρ‰Π΅Π½Π½Ρ‹ΠΌ Π½Π° Web-сайтС, прСдусмотрСн Π²Ρ‹Π²ΠΎΠ΄ ΠΎΠ±Ρ‰Π΅Π³ΠΎ количСства Π²Ρ‹Π·ΠΎΠ²ΠΎΠ² DllMain Π² соотвСтствии с ΠΈΡ… Ρ‚ΠΈΠΏΠ°ΠΌΠΈ.

β€’ Π”Π°ΠΆΠ΅ ΠΏΡ€ΠΈ Ρ‚Π°ΠΊΠΎΠΌ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠΈ сущСствуСт риск ΡƒΡ‚Π΅Ρ‡ΠΊΠΈ рСсурсов. НСкоторыС ΠΏΠΎΡ‚ΠΎΠΊΠΈ, Π½Π°ΠΏΡ€ΠΈΠΌΠ΅Ρ€ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΡ€ΠΈΠ΅ΠΌΠ° сообщСний, ΠΌΠΎΠ³ΡƒΡ‚ Π²ΠΎΠΎΠ±Ρ‰Π΅ Π½Π΅ Π·Π°Π²Π΅Ρ€ΡˆΠ°Ρ‚ΡŒΡΡ, ΠΈ поэтому Π½Π΅ Π±ΡƒΠ΄ΡƒΡ‚ отсоСдинСны ΠΎΡ‚ Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊΠΈ DLL. Для ΠΎΡΡ‚Π°ΡŽΡ‰ΠΈΡ…ΡΡ Π°ΠΊΡ‚ΠΈΠ²Π½Ρ‹Ρ… ΠΏΠΎΡ‚ΠΎΠΊΠΎΠ² функция ExitProcess Π²Ρ‹Π·ΠΎΠ²Π΅Ρ‚ DllMain с ΠΎΠΏΡ†ΠΈΠ΅ΠΉ DLL_PROCESS_DETACH, Π° Π½Π΅ DLL_THREAD_DETACH. Π’ Π΄Π°Π½Π½ΠΎΠΌ случаС Π½ΠΈΠΊΠ°ΠΊΠΈΡ… ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌ Π½Π΅ Π²ΠΎΠ·Π½ΠΈΠΊΠ°Π΅Ρ‚, ΠΏΠΎΡΠΊΠΎΠ»ΡŒΠΊΡƒ ΠΏΠΎΡ‚ΠΎΠΊ ΠΏΡ€ΠΈΠ΅ΠΌΠ° сообщСний Π½ΠΈΠΊΠ°ΠΊΠΈΡ… рСсурсов Π½Π΅ распрСдСляСт, Π° освобоТдСниС памяти происходит ΠΏΠΎ Π·Π°Π²Π΅Ρ€ΡˆΠ΅Π½ΠΈΠΈ процСсса. Однако, ΠΏΡ€ΠΎΠ±Π»Π΅ΠΌΡ‹ Π²ΠΎΠ·ΠΌΠΎΠΆΠ½Ρ‹ Π² Ρ‚Π΅Ρ… случаях, ΠΊΠΎΠ³Π΄Π° ΠΏΠΎΡ‚ΠΎΠΊΠΈ Ρ€Π°ΡΠΏΡ€Π΅Π΄Π΅Π»ΡΡŽΡ‚ Ρ‚Π°ΠΊΠΈΠ΅ рСсурсы, ΠΊΠ°ΠΊ Π²Ρ€Π΅ΠΌΠ΅Π½Π½Ρ‹Π΅ Ρ„Π°ΠΉΠ»Ρ‹. ΠŸΠΎΡΡ‚ΠΎΠΌΡƒ ΠΎΠΊΠΎΠ½Ρ‡Π°Ρ‚Π΅Π»ΡŒΠ½ΠΎΠ΅ Ρ€Π΅ΡˆΠ΅Π½ΠΈΠ΅ Π΄ΠΎΠ»ΠΆΠ½ΠΎ ΠΏΡ€Π΅Π΄ΡƒΡΠΌΠ°Ρ‚Ρ€ΠΈΠ²Π°Ρ‚ΡŒ созданиС глобально доступного списка рСсурсов. Π’ΠΎΠ³Π΄Π° участок ΠΊΠΎΠ΄Π°, ΡΠΎΠΎΡ‚Π²Π΅Ρ‚ΡΡ‚Π²ΡƒΡŽΡ‰ΠΈΠΉ ΠΎΠΏΡ†ΠΈΠΈ DLL_PROCESS_DETACH, ΠΌΠΎΠ³ Π±Ρ‹ Π²Π·ΡΡ‚ΡŒ Π½Π° сСбя просмотр этого списка ΠΈ освобоТдСниС Π½Π΅Π½ΡƒΠΆΠ½Ρ‹Ρ… рСсурсов.

ΠŸΡ€ΠΈΠΌΠ΅Ρ€: Π°Π»ΡŒΡ‚Π΅Ρ€Π½Π°Ρ‚ΠΈΠ²Π½Π°Ρ стратСгия создания бСзопасных Π±ΠΈΠ±Π»ΠΈΠΎΡ‚Π΅ΠΊ DLL с ΠΌΠ½ΠΎΠ³ΠΎ ΠΏΠΎΡ‚ΠΎΡ‡Π½ΠΎΠΉ ΠΏΠΎΠ΄Π΄Π΅Ρ€ΠΆΠΊΠΎΠΉ