다른 dll에서 정적 객체의 파괴 순서를 강제하는 방법은 무엇입니까?
-
22-08-2019 - |
문제
나는 2개를 가지고 있다 공전 2의 개체 다른 DLL:
객체 자원 (싱글톤) 및 객체 사용자.소멸자의 개체 사용자는 개체 리소스에 액세스해야 합니다.
개체 리소스가 개체 사용자보다 먼저 파괴되지 않도록 하려면 어떻게 해야 합니까?
해결책
해당 DLL이 언로드되면 글로벌 객체가 파괴됩니다. 따라서 '사용자'DLL은 아마도 '리소스'DLL에 의존 할 수 있으므로, '리소스'는 항상 '사용자'전에 파괴됩니다.
나는 또한이 질문이 존재한다면이 질문에 대한 좋은 대답에 관심이 있습니다. 지금까지, 나는 종료하기 전에 응용 프로그램에 의해 호출되어야하는 정리 기능을 사용하고 있으며, 파괴자에서는 무해한 코드 만 보관하고 있습니다.
다른 팁
2 개의 글로벌 변수를 동일한 DLL에 넣을 수 있다면 같은 이야기가 아닙니다. Jem이 자체 답장으로 말한 것처럼 DLL 분리 명령은 시스템에 의해 보장되지 않습니다. 따라서 2 개의 분리 된 DLL을 가질 때 큰 문제가있을 수 있습니다. 나는 Windows 시스템 전문가가 아니지만 Google을 살펴보면서 MSDN 블로거를 발견 한 것을 발견했습니다.
나에 따르면 솔루션이 더 쉬워집니다.이 경우 "garanteed dll detachement order"문제 (내가 이해하는 한 해결할 수없는) 문제를 해결할 필요가 없습니다.
그러나 여전히 새로운 문제를 해결해야합니다. Global Variable Passruction Order는 C ++ 언어에 의해 구분되지 않습니다. 그러나 이것은 다음과 같이 해결할 수 있습니다.
당신은 어떤 종류의 참조 쿠팅을 사용해야합니다. 부스트 :: shared_ptr은 트릭을 수행 할 수 있습니다.
전역을 선언하고 그런 식으로 정의하십시오.
boost::shared_ptr my_resource_ptr ( new Resource() ); // new operator is important here!
그런 다음 사용자 구현을 수정해야합니다 가게 자체 shared_ptr :
class User
{
...
boost::share_ptr a_resource_ptr;
...
};
모든 사용자 인스턴스가 파괴되지 않는 한, 자원 인스턴스를 '유지'하므로 글로벌 Shared_PTR이 파괴 되었음에도 불구하고 산기가 삭제되는 것을 방지합니다.
파괴 된 마지막 사용자 인스턴스는 (부당하게) 리소스 인스턴스를 삭제합니다.
당신이 사용하는 참조 계산, comptr, 당신 자신의 경우, 그것은 트릭을 수행해야합니다.
나는 당신이 다른 모듈에있는 글로벌의 파괴 순서를 바꿀 수 있다고 생각하지 않습니다. 참조 계산을 추가 할 가능성이 있습니까?
정말로 2개의 분리된 DLL을 얻고 싶은 경우 몇 가지 힌트를 드릴 수 있습니다.당신은의 사용을 고려할 수 있습니다 FreeLibrary()
Windows API에서.에 의해 명시된 바와 같이 msdn FreeLibrary()
카운터가 0에 도달하면 언로드되는 Dll에 대한 참조 카운터를 감소시킵니다.
약점:사용하여 FreeLibrary()
당신이 그것을로드하고 있음을 의미 LoadLibrary()
(msdn 링크) 그리고 이 라이브러리에서 함수를 호출하면 다음을 사용하고 있음을 의미합니다. GetProcAddress()
이는 정말 보기 흉한 코드로 이어질 수 있습니다.그리고 이는 각 함수의 주소를 저장하기 위해 Dll의 함수를 가리키는 전역 변수를 가져오는 등 코드의 일부 변경을 의미할 수도 있습니다.
구현하려는 경우:
- 라이브러리를 로드하고 해제해야 합니다.
main()
프로세스의 기능, - 또한 User 클래스를 구현하는 Dll에서 라이브러리를 로드하고 해제합니다.에서 구현하십시오.
DllMain()
이유가 다음과 같은 경우 이 Dll에 대한 함수DLL_PROCESS_DETACH
(보다 mdsn의 DllMain 링크.
따라서 "사용자" 라이브러리가 완료된 후에만 "리소스" 라이브러리를 언로드합니다.
원하시면 시도해 보시고 제가 구현한 적이 없으므로 작동하는지 알려주십시오.
추신:두 답변을 자세히 설명하면서 두 답변을 의미 있게 구분하기 위해 귀하의 질문에 대한 두 번째 답변을 게시했습니다.혼동하고 혼동하지 않으셨으면 좋겠습니다...