2011-01-11 3 views
5

일부 DLL을 공유 DLL로 옮깁니다 (일부는 Windows 후크라고 말하고 싶습니다).DLL의 델파이 finalizalization 코드

실제 기능은 현재 unit이며, 일부 코드는 initialization이고 일부는 finalization입니다.

나는 처음에 unit에서 library으로 직접 변환하는 것을 고려하고있었습니다. 그래서 beginend. 사이에 initialization 코드를 이동했습니다. 그런데 finalization 코드를 옮길 곳이 없다는 것을 깨달았습니다. 대신 특수 DLL 진입 점을 만들고 등록해야합니다.

내 질문입니다. unit의 모든 기능과 함께 initializationfinalization 코드를 남겨두고 uses 단위 인 library 스텁을 만들면됩니까? finalization이 호출됩니까?

답변

8

DLL의 단위 초기화 섹션에있는 코드는 DLL이 프로세스에 처음로드 될 때 실행됩니다. 종료 섹션은 DLL이 프로세스에서 언로드 될 때 시작됩니다.

Eugene은 DLLProc을 사용하여 더 세분화 된 제어를 할 수 있지만이 방법은 일반적으로 스레드 당 리소스에만 필요합니다. thread 로컬 스토리지

DLLMain 중에 수행 할 수있는 작업에 심각한 제한이 있으며 궁극적으로 이러한 초기화/종료 섹션이 라이브러리 내부에서 발생할 때 궁금합니다. MSDN 설명서는 기본적으로 몇 가지 작업을 수행 할 수 있지만 허용되는 동작 목록은 없다고 말합니다. 가장 가까운 것은 kernel32에서 함수를 호출 할 수 있다는 것입니다. 그렇지 않으면 모든 배팅이 꺼져 있습니다!

웹에 문제를 설명하는 기사가 많이 있지만 위에 링크 된 DLLMain에 대한 MSDN 항목 외에 Microsoft Best Practices for Creating DLLs을 읽는 것이 좋습니다.

MSDN에서 제공하는 유용한 조언은 DLL을 사용하기 전에 사용자가 초기화 함수를 호출하도록 라이브러리에서 요구할 수 있다는 것입니다. 일단 DLL로 끝나면 해당 finalization 함수가 호출됩니다. comctl32.dll을 사용하면이 관용구가 적용됩니다 (InitCommonControlsEx 참조).

내 자신의 코드에서 나는 대체 접근법을 선호합니다. 모든 유닛의 초기화 섹션은 초기화 및 종료 메소드를 등록합니다. 그런 다음 내 라이브러리에서 내 보낸 함수에 대한 첫 번째 호출에서 초기화 메소드가 등록 된 순서대로 실행됩니다.이미 내 라이브러리의 모든 시작/종료 지점을 제어 중이므로 구현하는 데 문제가 없습니다.

나는 이것이 당신이 요구 한 것 이상이라는 것을 알고 있지만, 문제를 디버그하기가 다소 어려워지는 것을 피하는 것이 도움이 될 수 있습니다.

+2

+1. 간단히 말해서 파이널 라이 제이션 섹션 *의 코드가 호출되지만 OS 로더 잠금으로 인해이 코드가 필요하지 않을 수 있습니다. 가능한 교착 상태 피하기 : 호스트 프로세스가 호출 할 수 있도록 명시 적 초기화 및 종료 함수를 내 보냅니다. –

+0

Old New Thing이 이유를 설명합니다. http://blogs.msdn.com/b/oldnewthing/archive/2004/01/27/63401.aspx –

+2

@Jeroen 그 기사에 연결하려고했는데, 큐 레이트의 달걀과 레이몬드 링크가 MS 링크 썩음에 의해 먹은 것으로 보이는 기사. 내가 찾은 최고의 참조 http://www.microsoft.com/whdc/driver/kernel/DLL_bestprac.mspx –

4

유닛의 초기화는 프로그램과 라이브러리 인 경우 호출됩니다.

마무리 단계와 동일합니다.

그렇습니다. 기기를 그대로두고 필요한 기능을 내보낼 수 있습니다.

0

DLLMain을 구현하고 각 상황에 대한 전용 프로 시저/함수를 호출하여 여러 상황 (처리 첨부, 스레드 첨부 등)을 처리하는 것이 좋습니다. 그런 다음 DLL에서 유닛으로 전환해야하는 경우 필요한 절차/함수를 초기화 및 종료에서 호출 할 수 있습니다. 그 이유는 DLL이 스레드에 연결/분리 될 때 미세 조정 컨트롤이 필요할 수도 있기 때문입니다 (시스템 전체의 후크를 설정할 때 발생합니다).

+0

당신은 그렇게해서는 안되며, The Old New Thing이 이유를 설명합니다 : http://blogs.msdn.com/b/oldnewthing/archive/2004/01/27/63401.aspx –

+0

@Jeroen 이것은 모든 단어입니다. 사실 시스템 전역의 후크를 구현할 때 (그리고 나는 그것들을 많이 썼다.) 많은 경우에 DLLMain을 사용하고 쓰레드 부착을 추적 할 필요가있다. 이는 시스템 전반에 걸친 훅의 특성 때문입니다. –

0

이것은 나에게도 마찬가지입니다. dll이 등록 될 때 스레드를 만들거나 일부 작업을 수행하는 초기화 섹션이 있다는 것을 알았습니다.

이 초기화 섹션을 제거했으며 정상적으로 작동했습니다. 초기화가 .EXE 응용 프로그램이 아닌 DLL 응용 프로그램이 필요하며, 이후

이 이 ModuleIsLib 라는 시스템 유틸리티에서 변수 플래그가 방금 수행이가도 수행 할 수 있습니다

initialization 

if not ModuleIsLib then 
begin 
// initialization stuff for .exe file 
end; 

finalization 섹션도 포함됩니다.

도움이 되었으면 좋겠다!