2011-08-24 2 views
1

나는 그들 사이의 데이터 공유 메커니즘을 제공하기 위해 동일한 프로세스에서 DLL을 조정하는 방법을 찾고있다. 목표는 모든 DLL에 대해 동일한 공유 코드를 사용하고 주 프로그램에 의해로드 된 첫 번째 프로그램이 공유 항목에 대한 관리자 역할을하는 방식으로 조정되도록하는 것입니다. 주 응용 프로그램을 수정할 수 없기 때문에 관리자를 설정하고 다른 DLL과 메모리 주소를 공유하는 것은 불가능합니다. 이 메커니즘을 사용하는 DLL 집합은 다양 할 수 있으므로이 중 하나가로드 될 것이라고 명시 할 수는 없습니다.호스트 프로그램의 도움없이 동일한 프로세스에서 여러 DLL을 어떻게 조정할 수 있습니까?

내가 고려한 한 가지 해결책은 프로세스의 환경 변수에 메모리 주소를 추가하는 것입니다. 첫 x 째 DLL은 환경 변수가 아직 설정되지 않았 음을보고 관리자 오브젝트를 작성하고 변수를 해당 주소로 설정합니다. 다른 DLL은 변수를보고 그로부터 관리자 객체에 대한 포인터를 생성합니다.

환경 변수가 이미 설정되지 않았고 SetEnvironmentVariable/GetEnvironmentVariable이 여러 가지 이유로 실패 할 수 있다는 보장이 없기 때문에 이것은 원하는 바에 가깝지만 다소 미숙 한 것처럼 보입니다.

더 나은 방법이 있나요? 프로세스의 컨텍스트에서 명명 된 포인터를 저장하고 검색하는 방법을 찾고 있지만, DLL을 협업하기위한 근본적인 문제에 대한 더 나은 솔루션을 가지고 있다면 이것을 받아 들일 수도 있습니다.

답변

1

이 작업을 수행하려면 GetModuleHandle()GetProcAddress()과 결합하십시오. 종속 DLL은 관리자 DLL에 대한 핸들을 얻은 다음 GetProcAddress()을 사용하여 내보낼 기호에서 포인터를 검색합니다.

또는 종속 DLL을 관리자 DLL과 동적으로 연결하고 extern 정의에 헤더 파일을 사용하십시오.


처음에는 질문을 읽었습니다. 그러나 위의 방법은 여전히 ​​유용 할 수 있습니다.

이러한 DLL은 모두 일부 구조 또는 기능을 가리키는 동일한 기호를 내보내도록 요구할 수 있습니다. 그런 다음 라이브러리 중 하나가 초기화되면 프로세스에서로드 된 모듈을 열거하고 해당 심볼을 찾을 수 있습니다. GetProcAddress()에 의해 반환 된 포인터의 역 참조가 널 포인터를 반환하면이 모듈이 처음으로로드되고 필요한 구조를 만들고 자체 변수를 설정해야합니다. 그렇지 않으면 포인터에서 얻은 값을 사용합니다.

이 방법은 이러한 모듈을 동시에 초기화 할 수있는 경우 경쟁 조건이 있습니다. 각 모듈이 통신 지점으로 사용할 수있는 단일 수퍼바이저 모듈을 갖는 것이 좋습니다.

+0

필자는 이것을 고려했지만 전용 관리자 DLL이 하나만있는 것을 선호합니다. DLL은 Game Maker 확장이며 제안 된 경로를 따르기 위해 관리자 DLL은이 시스템을 사용하는 모든 확장에 포함되거나 확장을 사용하려는 프로그래머가 수동으로 포함해야합니다. 이 여분의 의존성을 피하기 위해 – Medo42

+0

@cdhowie 모듈은 Windows에서 동시에 초기화 할 수 없습니다. 로더 락은 한 번에 하나의 DLL 엔트리 포인트 만 실행되도록 보장합니다. – bdonlan

+2

@ Medo42 : 솔루션은 각 DLL에 자체 관리자를 제공하는 것입니다. 관리자를 업그레이드해야 할 때 어떻게됩니까? 하나의 모듈이 이전 버전을 구현하고 먼저로드되면, 프로세스는 이전 버전을 사용해야합니다. 종속성은 성가신 일이지만이 상황은 관리자의 버전이 예측할 수 없으므로이 상황은 곧 DLL 지옥의 * 더 나쁜 버전이 될 것입니다. 개발자들에게 그렇게하지 마십시오. 적절한 헤더 파일에 대한 강한 의존성은 장기적으로 당신의 삶 (그리고 개발자들의 삶)을 훨씬 쉽게 만들어 줄 것이다. – cdhowie

2

만드는 방법은 named shared memory일까요?

프로세스 컨텍스트에서 유효한 주소를 얻는 번거 로움없이 메모리의 일부를 공유 할 수 있습니다. 로드 된 첫 번째 DLL은 공유 메모리를 만들고, 다음 DLL은 직접 메모리에 액세스 할 수 있으며,이 위에 자신의 메시징 API를 빌드 할 수 있습니다.

+0

그리고 당신은 동시 액세스가 있기 때문에 뮤텍스 등으로 접근을 감싸고 있는지 확인하십시오. + 감사합니다. @Adrien Plisson, 링크를 통해 제가 가지고있는 다소 관련된 문제를 해결할 수있었습니다. – ixe013

+0

이것은 일반적으로 작동하지만 명시 적으로 원하지 않는 프로세스간에 명명 된 공유 메모리가 공유되기 때문에 특별한주의가 필요합니다. 아직도 아이디어에 대한 upvote. – Medo42

0

cdhowie는 이것이 나쁜 생각 인 몇 가지 좋은 이유를 제공합니다.

그러나 전역 공유 메모리 네임 스페이스를 오염시키지 않고 실제로이 작업을 수행하려면 다음을 수행하십시오. DLL 클래스의 엔트리 포인트에 창 클래스를 등록하고 EXE의 인스턴스를 창 클래스의 hInstance 필드로 전달하십시오.

각 DLL은 클래스가 이미 등록되어 있는지 확인할 수 있습니다. 그렇지 않다면 스스로 등록하십시오. 창 클래스를 성공적으로 등록하는 첫 번째 DLL이 마스터가됩니다. 이후로드 된 DLL에서 마스터가 초기화 한 일부 구조에 대한 포인터를 얻으려면 해당 클래스의 메시지 전용 창을 만들고 SendMessage을 사용하여 (마스터 DLL에서) 창 프로 시저를 호출하십시오.

관련 문제