z

BLOG ARTICLE C++ | 3 ARTICLE FOUND

  1. 2006.11.24 Using Event Object
  2. 2006.11.24 Dll Class Exports
  3. 2006.11.24 Pointer Safe Delete Macro

Using Event Object

개발/Windows 2006. 11. 24. 15:07


Example Code
For an example that uses CreateEvent, see Using Event Objects.

Requirements
Client: Included in Windows XP, Windows 2000 Professional, Windows NT Workstation, Windows Me, Windows 98, and Windows 95.
Server: Included in Windows Server 2003, Windows 2000 Server, and Windows NT Server.
Unicode: Implemented as Unicode and ANSI versions. Note that Unicode support on Windows Me/98/95 requires Microsoft Layer for Unicode.
Header: Declared in Winbase.h; include Windows.h.
Library: Use Kernel32.lib.


See Also
Synchronization Overview, Synchronization Functions, CloseHandle, CreateProcess, DuplicateHandle, OpenEvent, ResetEvent, SECURITY_ATTRIBUTES, SetEvent, Object Names

Using Event Objects

Applications use event objects in a number of situations to notify a waiting thread of the occurrence of an event. For example, overlapped I/O operations on files, named pipes, and communications devices use an event object to signal their completion. For more information about the use of event objects in overlapped I/O operations, see Synchronization and Overlapped Input and Output.


In the following example, an application uses event objects to prevent several threads from reading from a shared memory buffer while a master thread is writing to that buffer. First, the master thread uses the CreateEvent function to create a manual-reset event object. The master thread sets the event object to nonsignaled when it is writing to the buffer and then resets the object to signaled when it has finished writing. Then it creates several reader threads and an auto-reset event object for each thread. Each reader thread sets its event object to signaled when it is not reading from the buffer.

#define NUMTHREADS 4

HANDLE hGlobalWriteEvent;

void CreateEventsAndThreads(void)
{
  HANDLE hReadEvents[NUMTHREADS], hThread;
  DWORD i, IDThread;

  // Create a manual-reset event object. The master thread sets
  // this to nonsignaled when it writes to the shared buffer.

  hGlobalWriteEvent = CreateEvent(
       NULL,         // no security attributes
       TRUE,         // manual-reset event
       TRUE,         // initial state is signaled
       "WriteEvent"  // object name
       );

  if (hGlobalWriteEvent == NULL)
  {
       // error exit
  }

  // Create multiple threads and an auto-reset event object
  // for each thread. Each thread sets its event object to
  // signaled when it is not reading from the shared buffer.

  for(i = 1; i <= NUMTHREADS; i++)
  {
       // Create the auto-reset event.
       hReadEvents[i] = CreateEvent(
           NULL,     // no security attributes
           FALSE,    // auto-reset event
           TRUE,     // initial state is signaled
           NULL);    // object not named

       if (hReadEvents[i] == NULL)
       {
           // Error exit.
       }

       hThread = CreateThread(NULL, 0,
           (LPTHREAD_START_ROUTINE) ThreadFunction,
           &hReadEvents[i],  // pass event handle
           0, &IDThread);
       if (hThread == NULL)
       {
           // Error exit.
       }
  }
}
Before the master thread writes to the shared buffer, it uses the ResetEvent function to set the state of hGlobalWriteEvent (an application-defined global variable) to nonsignaled. This blocks the reader threads from starting a read operation. The master then uses the WaitForMultipleObjects function to wait for all reader threads to finish any current read operations. When WaitForMultipleObjects returns, the master thread can safely write to the buffer. After it has finished, it sets hGlobalWriteEvent and all the reader-thread events to signaled, enabling the reader threads to resume their read operations.

VOID WriteToBuffer(VOID)
{
  DWORD dwWaitResult, i;

  // Reset hGlobalWriteEvent to nonsignaled, to block readers.

  if (! ResetEvent(hGlobalWriteEvent) )
  {
       // Error exit.
  }

  // Wait for all reading threads to finish reading.

  dwWaitResult = WaitForMultipleObjects(
       NUMTHREADS,   // number of handles in array
       hReadEvents,  // array of read-event handles
       TRUE,         // wait until all are signaled
       INFINITE);    // indefinite wait

  switch (dwWaitResult)
  {
       // All read-event objects were signaled.
       case WAIT_OBJECT_0:
           // Write to the shared buffer.
           break;

       // An error occurred.
       default:
           printf("Wait error: %d\n", GetLastError());
           ExitProcess(0);
  }

  // Set hGlobalWriteEvent to signaled.

  if (! SetEvent(hGlobalWriteEvent) )
  {
       // Error exit.
  }

  // Set all read events to signaled.
  for(i = 1; i <= NUMTHREADS; i++)
       if (! SetEvent(hReadEvents[i]) )
       {
           // Error exit.
       }
}

Before starting a read operation, each reader thread uses WaitForMultipleObjects to wait for the application-defined global variable hGlobalWriteEvent and its own read event to be signaled. When WaitForMultipleObjects returns, the reader thread's auto-reset event has been reset to nonsignaled. This blocks the master thread from writing to the buffer until the reader thread uses the SetEvent function to set the event's state back to signaled.

VOID ThreadFunction(LPVOID lpParam)
{
  DWORD dwWaitResult;
  HANDLE hEvents[2];

  hEvents[0] = *(HANDLE*)lpParam;  // thread's read event
  hEvents[1] = hGlobalWriteEvent;

  dwWaitResult = WaitForMultipleObjects(
       2,            // number of handles in array
       hEvents,      // array of event handles
       TRUE,         // wait till all are signaled
       INFINITE);    // indefinite wait

  switch (dwWaitResult)
  {
       // Both event objects were signaled.
       case WAIT_OBJECT_0:
           // Read from the shared buffer.
           break;

       // An error occurred.
       default:
           printf("Wait error: %d\n", GetLastError());
           ExitThread(0);
  }

  // Set the read event to signaled.

  if (! SetEvent(hEvents[0]) )
  {
       // Error exit.
  }
}

AND

Dll Class Exports

개발/Windows 2006. 11. 24. 15:02

출처 : MSDN '97

INFO: __declspec(dllexport) Replaces __export in 32-bit VC++


Last reviewed: September 30, 1997

Article ID: Q107501


이 기사의 정보는 다음에 적용된다 :

Microsoft Visual C++ 32-bit Edition, versions 1.0, 2.0, 4.0, 5.0

SUMMARY(요약)

Windows compiler를 위해 Visual C++과 함께 제공되는 __export 키워드는 Microsoft Visual C++ 32비트 컴파일러에서는 퇴색되었다. 이것의 Win32를 위한 적절한 기능은 __declspec을 dllexport 속성과 함께 사용하면서 달성될 수 있다. 4.0 버전의 Visual C++ 32-bit edition에서는 __export(혹은 _export) 키워드를 포함하는 컴파일링 코드는 다음 warnig 중 하나를 일으킨다:

C4236: nonstandard extension used : '__export' is an obsolete keyword,

  see documentation for __declspec(dllexport)

  -또는-

  C4226: nonstandard extension used : '__export' is an obsolete

  keyword

__export(혹은 _export) 키워드를 포함하는 컴파일링 코드는 1.0이나 2.x버전의 32비트 Visual C++에서 C4226 warning을 일으킨다.

MORE INFORMATION

__declspec 생성자는 Microsfot Win32 Software Development Kit(SDK)에 제공되는 툴로서 지원되지 않는다.

DLL 소스 코드를 Windows에서 Win32로 포팅할 때, __export의 각 인스턴스를 __declspec(dllexport)의 인스턴스로 각각 대체한다. __declspec(dllexport) 키워드는 데이터, 함수, 클래스, 클래스 멤버 함수를 익스포트하는데 사용될 수 있다. 예를 들어 :

/* exported function */

  __declspec( dllexport ) void func();


  /* exported data */

  __declspec( dllexport ) int i;


  // exported class

  class __declspec( dllexport ) DLLClass

  {

     ...

  };


  class DLLClass

  {

  public:

      // exported member function

      __declspec( dllexport ) void MemberFunction( void );

  };


아래의 샘플 코드는 __declspec(dllexport)와 __declspec(dllimport) 저장 클래스 속성을 DLL과 EXE에서 상대적으로 사용함으로써 클래스와 클래스 멤버 함수를 익스포트하는 법을 설명한다.


Sample Code

  /* DLL Sample: TESTDLL.CPP

  /* Compile options needed: /D"_X86" /MT TESTDLL.CPP /link

  /*                  /DLL /OUT:testdll.dll /implib:testdll.lib

  */


  #include <stdio.h>


  class DLLClass

      {

      public:

       // exported member function

       __declspec( dllexport ) void functionA( void ) {

           printf("\nIn Function A of the exported function");

       }

      };


  // exported class

  class __declspec( dllexport) ExportDLLClass

      {

      public:

       void functionB(void) {

          printf("\nIn Function B of the exported class");

       }

      };


  // exported instance of the DLLClass

  __declspec(dllexport) DLLClass test;


  /* Source that calls the DLL Sample: CALLDLL.CPP

  /* Compile options needed: /D"_X86" /D"_CONSOLE" /ML CALLDLL.CPP

  /*                  TESTDLL.LIB

  */


  #include <stdio.h>


  class DLLClass

      {

      public:

       // imported member function

       __declspec( dllimport ) void functionA( void );

      };


  class __declspec( dllimport) ExportDLLClass

      {

      public:

       void functionB(void);

      };


  __declspec( dllimport ) DLLClass test;


  void main(void)

  {

     ExportDLLClass TestClass;


     test.functionA();

     TestClass.functionB();

  }


REFERENCES

익스포트에 대한 더 많은 정보를 원하면, 다음 단어로 Microsoft Knowledge Base에서 검색하라

__export and def and prolog and dllexport

dllexport와 dllimport 저장 클래스 속성을 사용해 Win32를 위한 DLL을 생성하는 데 대한 더 많은 정보를 원한다면, Visual C++ 32-bit Edition과 함게 제공되는 "Programming Techniques" 매뉴얼의 Chapter 4를 참조하거나, Visual C++ Books Online에서 dllexport나 dllimport, export를 검색해 보라. > Visual Workbench(역자주 : Visual Studio메뉴 의미하는 듯)에서 Help를 선택하고, Keyword Search를 고른다.


Additional query words: 8.00 9.00

Keywords : CLngIss kbfasttip

Version : WINDOWS NT:1.0,2.0,4.0,5.0;

Platform : NT WINDOWS

THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: September 30, 1997

ⓒ 1998 Microsoft Corporation. All rights reserved. Terms of Use

AND

#define SAFE_DELETE(ptr) {if(ptr){ delete (ptr); (ptr)=NULL;}}
AND