본문 바로가기

개발 Note/UI Framework 개발하기

Process 모델을 설계시 같이 고민하고 있는 부분이 Dynamic Linking & Dynamic Loading 이다.

반응형

DLL Win32


[In-Process 방식]
내가 System part에 속하지 않아서 Process model을 설계하는 것에 대해 그다지 관심을 두지 않고 있지만,
지금 System 팀에서 아직 Process model의 architecture 를 설계 방향을 잡지 못하고 있다.
음, 아무래도 DLL 과 COM 의 구현 등에 대해서 래퍼런스가 될만한 프로세스 모델을 찾고,
좀더 정확하게 DLL의 동작및 메모리 구조 등에 대해서 더 공부를 해봐야 할듯하다.


- DLL Win32 의 경우 해당 DLL이 로드된 물리적인 메모리 영역이 해당 DLL을 로드한 어플리케이션의 프로세스 주소 영역게 메핑된다. 즉, Win32 DLL 은 자신을 로드한 어플리케이션의 일부가 된다.
따라서 DLL 함수의 매개변수에 포인터가 넘어올때 DLL함수가 이 포인터를 통하여 접근할 수 있는 주소 영역을 완전히 유효하다.


http://msdn.microsoft.com/en-us/library/ms686958(VS.85).aspx
Using Shared Memory in a Dynamic-Link Library

The following example demonstrates how the DLL entry-point function can use a file-mapping object to set up memory that can be shared by processes that load the DLL. The shared DLL memory persists only as long as the DLL is loaded. Applications can use the SetSharedMem and GetSharedMem functions to access the shared memory.

DLL that Implements the Shared Memory

The example uses file mapping to map a block of named shared memory into the virtual address space of each process that loads the DLL. To do this, the entry-point function must:

  1. Call the CreateFileMapping function to get a handle to a file-mapping object. The first process that loads the DLL creates the file-mapping object. Subsequent processes open a handle to the existing object. For more information, see Creating a File-Mapping Object.
  2. Call the MapViewOfFile function to map a view into the virtual address space. This enables the process to access the shared memory. For more information, see Creating a File View.

Note that while you can specify default security attributes by passing in a NULL value for the lpAttributes parameter of CreateFileMapping, you may choose to use a SECURITY_ATTRIBUTES structure to provide additional security.


[MSDN 참고 내용]

Visual C++
DLL의 데이터를 응용 프로그램 또는 다른 DLL과 공유하려면 어떻게 합니까?

Win32 DLL은 호출 프로세스의 주소 공간에 매핑됩니다. 기본적으로 DLL을 사용하는 각 프로세스에는 모든 DLL의 전역 및 정적 변수에 대한 자체 인스턴스가 있습니다. DLL이 다른 응용 프로그램이 로드한 DLL의 다른 인스턴스와 데이터를 공유해야 할 경우 다음 방법 중 하나를 사용할 수 있습니다.

  • data_seg pragma를 사용하여 명명된 데이터 섹션을 만듭니다.

  • 메모리 매핑 파일을 사용합니다. 메모리 매핑 파일에 대한 Win32 설명서를 참조하십시오.

다음은 data_seg pragma 사용 예입니다.

#pragma data_seg (".myseg")
   int i = 0; 
   char a[32]n = "hello world";
#pragma data_seg()

data_seg를 사용하여 새로운 명명된 섹션(이 예제에서는 .myseg)을 만들 수 있습니다. 일반적인 사용 방법은 명확하게 데이터 세그먼트 .shared를 호출하는 것입니다. /SECTION:.MYSEC,RWS 링커 옵션을 사용하거나 .def 파일의 새로운 명명된 데이터 섹션에 대해 올바른 공유 특성을 지정해야 합니다.

공유 데이터 세그먼트를 사용하기 전에 몇 가지 제한 사항을 고려해야 합니다.

  • 공유 데이터 세그먼트의 변수는 정적으로 초기화되어야 합니다. 위의 예제에서 i는 0으로 초기화되며 a는 hello world로 초기화된 32문자입니다.

  • 모든 공유 변수는 지정된 데이터 세그먼트의 컴파일된 DLL에 있어야 합니다. 배열이 크면 DLL도 커집니다. 초기화된 모든 전역 변수에 대해 해당됩니다.

  • 프로세스 관련 정보를 공유 데이터 세그먼트에 저장하지 마십시오. 대부분의 Win32 데이터 구조나 값(예: HANDLE)은 단일 프로세스의 컨텍스트 내에서만 유효합니다.

  • 각 프로세스는 자체 주소 공간을 얻습니다. 공유 데이터 세그먼트에 포함된 변수에는 포인터가 저장되지 않는다는 점에 주목할 필요가 있습니다. 포인터는 한 응용 프로그램에서는 절대적으로 유효하지만 다른 응용 프로그램에서는 그렇지 않습니다.

  • 각 프로세스의 가상 주소 공간 내의 다른 주소로 DLL 자체가 로드될 수 있습니다. DLL이나 다른 공유 변수에서 함수에 대한 포인터를 사용하는 것은 안전하지 않습니다.

뒤의 세 가지 항목은 메모리 매핑된 파일 및 공유 데이터 세그먼트에 적용됩니다.

메모리 매핑된 파일의 시작 위치를 알 수 없으므로 메모리 매핑된 파일이 공유 데이터 섹션보다 유용합니다. 개발자는 공유 메모리 내부에 있는 모든 데이터에서 "공유 메모리 섹션의 시작 위치를 기준으로 하는 오프셋"을 사용하여 포인터와 유사한 동작을 구현할 수 있습니다. 빠르고도 간편한 작업을 위해 __based 포인터가 강력히 권장됩니다. 그러나 기준(또는 메모리 매핑된 파일의 시작 위치)은 각 프로세스마다 달라질 수 있으므로 __based 포인터의 기준을 저장하는 변수 자체는 공유 메모리에 있을 수 없습니다.

이러한 제한이 C++ 클래스에서는 중요한 의미를 갖습니다.

  • 가상 함수를 사용하는 클래스에는 항상 함수 포인터가 있습니다. 가상 함수를 사용하는 함수는 공유 데이터 세그먼트에 저장될 수 없으며 메모리 매핑된 파일에도 저장될 수 없습니다. 이 점은 MFC 클래스나 MFC에서 상속된 클래스에게 중요합니다.

  • 통계 데이터 멤버는 전역 변수와 동등한 변수로 구현됩니다. 따라서 각 프로세스에는 해당 클래스의 정적 데이터 멤버에 대한 자체 복사본이 있습니다. 정적 데이터 멤버를 사용하는 클래스는 공유될 수 없습니다.

  • 공유 데이터 세그먼트의 초기화 요구 사항으로 인해 C++ 클래스에서 특별한 문제가 제기됩니다. 공유 데이터 세그먼트에 CTest Counter(0); 같은 문이 있으면 Counter 개체는 DLL을 로드하는 각 프로세스에서 초기화되어 매번 개체 데이터가 0으로 됩니다. 링커가 DLL을 만들 때 초기화하는 내장 데이터 형식과는 다릅니다.

이러한 제한 때문에 프로세스 간에 C++ 개체를 공유하는 것은 바람직하지 않습니다. 일반적으로 C++를 사용하여 프로세스 간에 데이터를 공유하려면, 데이터를 공유하기 위해 내부적으로 메모리 매핑된 파일을 사용하는 클래스를 작성하되 클래스 인스턴스는 공유하지 마십시오. 이런 클래스를 개발할 때는 신중해야 하지만 이런 방식으로 응용 프로그램 개발자는 데이터 공유에 의한 부작용을 완벽하게 제어할 수 있습니다.

명명된 데이터 섹션을 만드는 방법에 대한 자세한 내용은 http://support.microsoft.com의 기술 자료 문서를 참조하십시오.

  • "How to Share Data Between Different Mappings of a DLL"(Q125677)

  • "Specifying Shared and Nonshared Data in a DLL"(Q100634)

  • "Sharing All Data in a DLL"(Q109619)

  • "Memory in Shared Code Sections Is Not Shared Across Terminal Server Sessions"(Q251045)