2013-08-13 2 views
5

인터페이스를 반환하는 함수를 내보내는 dll이 있습니다.FreeLibrary가 호출되기 전에 인터페이스 인스턴스가 해제되도록하려면 어떻게해야합니까?

내 보낸 함수를 호출하는 데 사용되는 LoadLibrary, GetProcAddress 및 FreeLibrary 함수에 대한 래퍼를 만들었습니다.

TInterfaceGetter = class 
private 
... 
public 
    constructor Create; 
    destructor Destroy; override; 
    function GetInterface: IMyInterface; 
end; 

이 래퍼 게으른로드 DLL 및 GetInterface이 처음이라고 내 보낸 함수의 모듈 핸들 및 PROC 주소를 캐시합니다. FreeLibrary에 대한 호출은 래퍼의 소멸자에서 발생합니다.

래퍼를 해제 한 후 클라이언트 코드가 인터페이스 참조에 멈추는 경우를 제외하면 모든 것이 훌륭하게 작동합니다. 인터페이스 참조가 결국 범위를 벗어날 때 _IntfClear에 대한 결과 호출은 dll과 사용중인 메모리가 클라이언트의 메모리 공간에서 이미 언로드 되었기 때문에 액세스 위반을 발생시킵니다.

어떻게해야합니까? COM 구현이 어떻게이 시나리오를 처리합니까?

답변

6

COM은 책임을 DLL로 옮김으로써이 문제를 처리합니다. DLL은 DllCanUnloadNow이라는 함수를 구현하고 내 보내야합니다. COM은 때때로이 함수를 호출하고 TRUE를 반환하면 DLL이 언로드 될 수 있습니다.

그래서 함수는 어떻게 알 수 있습니까? DLL은 DllGetClassObject에 대한 호출을 통해 얼마나 많은 객체를 제공했는지 추적하며, 얼마나 많은 객체가 아직 살아 있는지 알 수 있습니다. Delphi의 기본 COM DLL 구현에서는 각 객체가 자체 참조 카운트를 유지하는 방식과 마찬가지로 전역 객체 수를 유지합니다. 예를 들어, ComServ.pas의 구현을 참조하십시오.

동일한 기술을 사용할 수 있습니다. 귀하의 GetInterface 기능이 제공하는 것과 출시 된 내용을 추적하십시오. 호스트 프로그램이 라이브러리를 언로드하는 것이 안전한지 여부를 묻는 다른 함수를 내 보냅니다.

대체 방법은 DLL을 실제 COM DLL로 변경하는 것입니다.

관련 문제