2009-07-25 7 views
3

모듈/공유 객체/DLL을 통해 런타임에 확장 할 수있는 C로 응용 프로그램을 작성하고 있습니다. 이러한 모듈은 기존 프로그램의 API를 사용할 수 있지만 나중에로드 된 모듈에서 사용할 새로운 기능을 제공 할 수도 있으므로 모듈이 서로에 대한 종속성을 가질 가능성이 있습니다.Windows에 DLL이있는 동적 모듈

현재 리눅스에서 나의 접근 방식은 모든 모듈이 의존하는 다른 모듈 이름의 목록을 반환하는 depends() 함수를 정의하도록하는 것입니다. 그런 식으로 모든 모듈을 컴파일하고 링크하여 dlopen() 및 RTLD_LAZY을 사용하여 모듈을로드하고 종속성을 먼저 확인한 다음 RTLD_GLOBAL으로 완전히로드 할 수 있습니다. 이것은 제대로 작동하고 내가 원하는 것을 정확하게 수행합니다. 또한 모듈을 다른 버전으로 대체 할 수 있습니다. 다른 모듈은 모듈에 따라 다른 모든 모듈을 다시 컴파일하지 않아도됩니다.

Windows로 이식 할 때 실제 문제가 발생합니다. 첫째, 모든 종속성의 내보내기 심볼 테이블을 제공하지 않고 DLL을 링크하는 방법을 찾지 못했습니다. 간과 한 것이 있습니까?

두 번째로 Windows API의 LoadLibraryEx는 종속성을 처리하지 않고 지연된 모든 DLL을로드하기 때문에 지연로드를 수행 할 수없는 것 같습니다. 앞으로 모듈을 실제로로드하기 전에 버전 검사를 수행하고 싶기 때문에, 내가 원하는 바가 아닙니다. 이 행동을 피할 수있는 방법이 있습니까?

세 번째로 이상한 점은 DLL에 따라 다른 모든 모듈을 다시 컴파일하지 않으면 DLL을 대체 할 수 없다는 것입니다. 때때로 실제로 작동하지만 일반적으로 야생 일이 생기기 시작하거나 프로그램이 segfault합니다.

Windows와 같은 모듈 형 응용 프로그램을 작성할 수 있습니까? 어떤 제안이나 다른 접근법을 높이 평가합니다!

업데이트 : 그냥 (나뿐만 아니라 Windows에서하고 싶은) 내 모듈은 리눅스에서 각각 다른 기능을 사용하는 방법에 대한 몇 가지 설명을 제공 할 수는 : 모든 모듈 그냥 전화하고 싶은 다른 모듈의 이름을 반환 설명 된 depends() 함수에서 함수를 가져 와서 해당 헤더를 포함하고 랩핑하지 않고 코드에서 직접 사용 함수를 호출합니다. 이것은 Linux가 공유 객체에 대한 링크시 모든 심볼을 해석하도록 요구하지 않기 때문에 가능합니다.

답변

4

__declspec(dllexport)을 사용하여 모든 기능을 수동으로 내보내고 GetProcAddress을 사용하여로드 할 수 있습니다. 이 경우 각 함수의 서명을 알아야하며 C 함수로만 제한됩니다. 그러나 이것이 작동 할 것입니다. 두 모듈을 모두 컴파일하면 C 함수는 C++ 클래스도 반환 할 수 있습니다. GetProcAddress & LoadLibrary을 사용하면 모듈이 완전히 독립적이됩니다. 기본적으로, 당신은 수동으로 링크를하지만, 이해할 수있는 것처럼, 이것이 리눅스에서하는 일입니다.

LoadLibary은 라이브러리가 의존하는 라이브러리 만로드하므로 서로로드되지 않도록하십시오. 그것들은 정말로 독립적이다. 그렇지 않으면 하나의 라이브러리를 변경해도 다른 라이브러리를 재 컴파일하지 않아도된다.

COM과 같은 것을 사용하는 것이 좋습니다. 각 라이브러리가 개별 기능 대신 인터페이스를 반환하도록하십시오. 그렇게하면 전체 DLL을로드하고 함께 쉽게 연결할 수 있습니다 (DLL 전달 -> 객체 전달). XPCOM과 COM을 살펴보면, 실제로는 매우 쉽습니다.

+1

좋아,'GetProcAddress'에 대한 제안은 이미 약간 도움이됩니다. 방금 시도해 보았고 DLL에서 함수를 호출하는 것은 그 방식으로 연결하지 않고도 작동합니다.그러나 이것은 모듈에 리눅스의 것과 같은 것에 의존하는 헤더를 포함시킬 수는 없다는 것을 의미 할 것입니다. 부모 모듈에서 무엇이든 호출하기 전에 먼저 GetProcAddress와 함께 필요한 모든 함수 포인터를 먼저 수집해야합니다. COM의 팁을 이용해 주셔서 감사합니다. – smf68

+1

네,하지만 제가 말씀 드렸듯이, 하나의 모듈에 대한 모든 기능을 클래스로 그룹화하고 호출하십시오. 그것은 훨씬 쉬우 며 또한 수출 기호의 수를 줄입니다. 상속 관계가 없으므로 실제로는 COM이 아닙니다. 단지 유사한 생각을 기반으로합니다. 클라이언트는 인터페이스를 사용하며 실제 구현을 알지 못합니다. – Anteru

+0

흥미로운 주제. 따라서 모듈 개발자가 WinAPI 및/또는 COM에 대한 지식을 가지고 있어야만이 작업을 수행 할 수 있습니다. :-( – Gregor