2008-10-19 3 views
1

컴파일 된 언어 (C#/C/C++/D)에서 플러그인을 수행하는 "일반적인"방법은 무엇입니까? 나는 특별히 언어에 무관심한 접근법에 관심이 있지만 특정 언어는 받아 들일 수없는 것이 아닙니다.응용 프로그램의 플러그인 시스템에 권장되는 사항은 무엇입니까?

당분간 "컴파일 시간"플러그인 접근법 (코드 포함 여부와 모든 것이 작동 함)은 유효하지만보다 동적 인 접근 방식으로 마이그레이션 할 수있는 것들이 선호됩니다. BTW 플러그인은 노예가 아니라 주인이 될 것이다 : 실행시의 형태에 관한

, 나는 플러그인을로드의 메커니즘에 더 관심과 이것 저것 플러그인/응용 프로그램 인터페이스를 설계보다

편집 해요 . 플러그인의 기본 동작은 주어진 상황에서 "기본 사항"을 수행하고 작동해야하는 것을 얻기 위해 사용해야하는 환경 객체를 제공해야한다는 것입니다.

+0

첫 번째 아이디어는 시작시 플러그를 등록하는 정적 생성자를 플러그인에 포함시키는 것이 었습니다. 그러나 C# (내가 작업해야하는 언어 중 하나)은 요청시를 제외하고 정적 생성자를 호출하지 않는 것으로 보이며 작동하지 않습니다. 어떤 아이디어? – BCS

답변

2

컴파일 된 언어의 경우 (컴파일 된 것은 프로그램이 가상 컴퓨터 없이도 원시 실행 파일로 실행된다는 것을 의미 함) 플랫폼 관련 공유 라이브러리 접근 방식을 사용해야합니다. Windows에서 이것은 DLL 사용을 의미합니다.

플러그인 인터페이스는 기능 집합 (특정 이름, 인수 및 호출 규칙)으로 정의됩니다. 그런 다음 공유 라이브러리 내의 함수 주소를로드하고 마을로 이동합니다. Windows에서 이것은 GetProcAddress()을 사용한 다음 C에서 적절한 유형의 함수 포인터로 반환 값을 캐스팅하거나 사용중인 언어에 해당하는 것이 무엇이든지 의미합니다.

더 바람직하거나 바람직하지 않은 또 다른 옵션은 네이티브 응용 프로그램 내에서 다른 언어로 가상 컴퓨터를 실행하고 해당 언어의 코드를 플러그인으로 사용하는 것입니다. 예를 들어 CPython을 사용하여 Python VM을 실행하고 Python 모듈을 동적으로로드 할 수 있습니다.

+0

좋은 답변입니다. 그게 제가 찾고있는 정보 유형입니다. – BCS

0

void 레지스터 (EventSource)가있는 인터페이스는 예를 들어 ASP.NET의 IHttpModule.Init(HttpApplication을 참조하십시오. (불가피하게 IPluginEx, IPlugin2, IPlugin2Ex 등으로 이어지는)을 IPlugin 인터페이스를 확장 할 필요없이, 필요에 따라이 이벤트를 추가 할 수있는 응용 프로그램의 저자 (누가 EventSource를 제어) 할 수 있습니다

+0

일반적으로 유용 할 수 있지만 등록 호출은 어떻게 호출 되나요? 누가 그것을합니까, 메인 애플 리케이션이 그것을 호출하는 것으로 알려져 있습니까? – BCS

1

나는 것으로 나타났습니다 플러그인에 대한 어려운 부분은 플러그인을 찾고 의존성을 해결하고 버전 문제를 처리하는 것입니다. 이러한 문제를 어떻게 처리 할 것인가는 개발자와 플러그인 작성자에게 명확해야합니다. 이러한 문제가 잘못되면 통증이 없어집니다. 필자는 플러그인 언어를 사용하는 스크립팅 언어와 효과적인 아이디어에 대한 아이디어를 살펴볼 것입니다.

정적 생성자는 나쁜 의미에서 "영리한"경우가 많습니다. 동적 인 경우에 한 번에 하나씩 플러그인 (C/C++ : dlopen 및 Linux의 친구)을로드해야하기 때문에 그렇게 할 때 플러그인을 명시 적으로 초기화해야 할 수도 있습니다. 무엇보다도, 그것은 당신에게 예상 API없이 플러그인을 거부 할 수있는 기회를 줄 수 있습니다.

참고 : 플러그인에 동적로드 라이브러리를 사용할 필요가 없습니다. 다른 메커니즘도 사용할 수 있습니다 : 공유 메모리, 소켓 등 ...

+0

장기적으로 "영리한"것은 피하고 싶습니다. 짧은 실행에서는 초기 후킹 (다시 컴파일하는 시간 플러그인)에 적합 할 수도 있습니다. – BCS

3

Mono.Addins은 .NET 용 좋은 해결책 인 것 같습니다. 나는 API를 사용하여 repo에서 플러그인 (또는 addins)을 다운로드하여 실행중인 어셈블리에 동적으로로드 할 수 있다고 믿습니다.

+0

나는 사용자가 아직 그것을 얻지 못하는 것을보고 있습니다. 나는 주 코드베이스에 모든 추가 기능을 해킹하지 않아도되는 방법을 계속 연구 중이다. – BCS

+0

http://codeelegance.blogspot.com/2009/06/monoaddins-in-msnet-20-application-part.html –

0

내가 사용한 (.NET에서) 접근법은 호스트가 플러그인에 대한 초기 호출 (Reflection을 통해)을 시작하고, 플러그인을 시작하고, 플러그인이 저장하는 호스트에 대한 참조를 전달하도록하는 것입니다. 그런 다음 플러그인은 필요에 따라 리플렉션을 통해 호스트의 메소드를 호출합니다.

대부분의 플러그인에서 호출은 대개 ​​다른 방향으로 이루어집니다 (즉, 호스트가 필요에 따라 플러그인을 호출 함). 필자의 경우 플러그인에는 호스트 기능을 사용해야하는 UI 요소가있었습니다.

+0

광산은 두 번째 방향으로갑니다. – BCS

1

정말로 원하는 일에 달려 있습니다. Emacs와 Gimp에서 볼 수있는 일반적인 유닉스 패턴은 해석 된 컴포넌트가 모든 것을하기 위해 사용하는 필수 기능을 제공하는 작은 컴파일 된 컴포넌트로 구성된 프로그램을 작성하는 것이다. 앱 상단에 구축 할 수있는 새로운 기능을 제공하는 플러그 인은 쉽게 사용할 수 있지만 제공 할 수있는 프리미티브에는 매우 유연해야합니다. 반대편 극단에서는 여러 형식으로 저장할 수있는 사진 편집기를 상상해보십시오. 사람들이 자신의 파일 형식 핸들러를 작성할 수있게하려고합니다. 이를 위해서는 코드가 간단한 프리미티브 집합을 사용하고 런타임에 구현을 선택해야합니다. 똑바로 (유닉스) C에서 dlopen을 사용하고 C++에서는 extern C를 사용하여 수행 할 수있는 작업과 작업을 제한합니다. Objective-C에는 당신을 위해 그것을 할 클래스가 있습니다. 첫 번째 경우에는 통역관을 만들거나 재사용하므로 자유롭게 통치 할 수 있습니다.

0

낮은 수준의 모듈 구현 문제 (예 : Windows DLL 및 구현 문제), 제가 사용하는 게임 엔진은 DLL에 전역 등록 기능을 가지고 있으며 플러그인 디렉토리의 모든 DLL에서이를 찾아서 호출하려고합니다. 등록 기능은 기능을 노출하는 데 필요한 부기를 수행합니다.

1

각 플러그인이 공통 기능 집합의 다른 구현을 캡슐화하는 슬레이브 유형 플러그인의 경우 호스트 응용 프로그램에 알려진 플러그인 폴더에 DLL을 보관합니다 (예 : "c : \ program files \ myapp \ 플러그인), 다음 반사를 통해 호스트에서 DLL을 호출합니다.

을 당신 각 DLL이 설치되어 정교한 등록 과정의 일종을 할 수있는,하지만 난 - 인 - 플러그인 간단한에 문제를 경험 한 적이 한 폴더 접근 방식

편집 : C#에서 이렇게하려면 공용 클래스를 DLL ("Plugin"또는 기타)에 추가하고 필요한 func 거기에. 그런 다음 호스트에서 Plugin 유형의 객체를 만들고 그 메소드를 호출합니다 (모두 Reflection을 사용).

+0

이 접근 방법에 대한 구체적인 조언이 있으십니까? 상황은 dllmain 함수가 내부 등록을 수행해야합니까, 아니면 앱이 다른 함수를 호출해야합니까? dll의 일부로 Extender가 연결되고 아래에 빌드되는 일종의 표준 심이어야합니까? – BCS

+0

C#에서는 공용 클래스를 DLL ("Plugin"또는 기타)에 추가하고 거기에 필요한 함수를 구현하기 만하면됩니다. 그런 다음 호스트에서 Plugin 유형의 객체를 만들고 그 메소드를 호출합니다 (모두 Reflection을 사용). – MusiGenesis

+0

내가 아는 바로는 C 또는 C++에서 플러그인 아키텍처를 구현하는 것이 훨씬 어려우며 논평 할 자격이 없습니다. 하지만 나는 D.보다 더 자격이있어.:) – MusiGenesis

관련 문제