Adobe Photoshop을 사용한 적이 있습니까? 평신도의 경우 플러그인은 외부에서 응용 프로그램에 제공된 코드 블록 (예 : DLL)입니다. 플러그인과 일반 DLL의 차이점은 플러그인이 부모 응용 프로그램의 기능을 확장 할 수 있다는 것입니다. 예를 들어, Photoshop 자체에는 많은 양의 이미지 처리 기능이 없습니다. 플러그인을 추가하면 Blur, Spot 및 기타 모든 스타일과 같은 놀라운 효과가 있으며 부모 응용 프로그램 자체는 없습니다.
이것은 이미지 처리 프로그램에 매우 좋지만 플러그인을 지원하는 상업용 응용 프로그램을 완료하기 위해 많은 노력을 기울여야합니까? 예를 들어, 신청서가 일부 보고서를 생성 할 것이라고 가정 해 봅시다. 고객은 계속해서 업데이트를 요청하거나 새로운 보고서를 추가 할 것입니다. 너무나도없는 솔루션 인 Report Smith와 같은 외부 보고서 생성기를 사용할 수 있으며 추가 파일, 사용자를위한 추가 교육 등을 게시해야합니다. QuickReport를 사용할 수 있지만 버전 제어 악몽에 빠질 수 있습니다. 글꼴을 변경할 때마다 응용 프로그램을 재건하려면 글꼴을 변경합니다.
그러나 플러그인에 보고서를 작성하는 한 사용할 수 있습니다. 새 보고서가 필요하십니까? 문제 없습니다. DLL을 설치하면 다음에 응용 프로그램이 시작될 때 확인할 수 있습니다. 또 다른 예는 외부 장치 (예 : 바코드 스캐너)의 데이터를 처리하는 응용 프로그램입니다. 각 장치 인터페이스 처리 루틴을 플러그인으로 작성하면 부모 애플리케이션을 변경하지 않고도 최대의 확장 성을 달성 할 수 있습니다.
시작하기
코드를 작성하기 전에 가장 중요한 것은 응용 프로그램이 확장 해야하는 기능을 파악하는 것입니다. 이는 플러그인이 특정 인터페이스를 통해 상위 응용 프로그램과 상호 작용하기 때문에 필요에 따라 정의되기 때문입니다. 이 기사에서는 플러그인이 상위 응용 프로그램과 상호 작용하는 몇 가지 방법을 보여주는 3 개의 플러그인을 작성합니다.
플러그인을 DLL로 만들 것입니다. 그러나이 작업을 수행하기 전에로드하고 테스트하기 위해 쉘을 만들어야합니다. 그림 1은 첫 번째 플러그인이로드 된 후 테스트 프로그램을 보여줍니다. 첫 번째 플러그인은 큰 것을 달성하지 못하며 실제로는 자신을 설명하는 문자열을 반환하는 것입니다. 그러나 중요한 포인트를 확인합니다. 플러그인 애플리케이션이 있거나 없으면 제대로 작동합니다. 플러그인이없는 경우 설치된 플러그인 목록에 표시되지 않지만 응용 프로그램은 여전히 기능을 정상적으로 수행 할 수 있습니다.
플러그인 쉘과 일반 애플리케이션의 유일한 차이점은 사용 절을 사용하는 프로젝트 소스 파일의 Sharemem 장치와 플러그인 파일을로드하는 코드입니다. 자체와 하위 DLL간에 문자열 매개 변수를 전달하는 응용 프로그램은 DelphimM.Dll의 인터페이스입니다 (Delphi는이 파일을 제공합니다). 이 쉘을 테스트하려면 DelphiM.dll 파일을 Delphi/bin 디렉토리에서 PATH ENTERNING 변수 또는 응용 프로그램이있는 디렉토리에 포함 된 경로로 복사해야합니다. 파일은 최종 버전이 릴리스 될 때 동시에 배포해야합니다.
플러그인은 주 창의 FormCreate 이벤트에서 호출되는 LoadPlugins 프로세스를 통해이 테스트 쉘에로드됩니다 (그림 2 참조). 이 프로세스는 FindFirst 및 FindNext 기능을 사용하여 응용 프로그램이있는 디렉토리에서 플러그인 파일을 찾습니다. 파일을 찾은 후 그림 3에 표시된 LoadPlugins 프로세스를 사용하여로드하십시오.
{응용 프로그램 디렉토리에서 플러그인 파일 찾기}
절차 tfrmmain.loadplugins;
var
SR : Tsearchrec;
경로 : 문자열;
발견 : 정수;
시작하다
경로 : = ExtractFilePath (Application.Exename);
노력하다
찾았습니다 : = findfirst (path + cplugin_mask, 0, sr);
찾은 동안 = 0이 시작됩니다
loadplugin (SR);
발견 : = findNext (sr);
끝;
마지막으로
findclose (sr);
끝;
끝;
{지정된 플러그인 DLL을로드하십시오.
절차 tfrmmain.loadplugin (sr : tsearchrec);
var
설명 : 문자열;
libhandle : 정수;
설명 : tplugindescribe;
시작하다
libhandle : = loadlibrary (pchar (sr.name));
libhandle $#@60; $#@62;
시작하다
SEFFICEPROC : = getProcAddress (libhandle, cplugin_describe);
할당 된 경우 (SEFLEPROC)
DescriptionProc (설명);
memplugins.lines.add (설명);
끝
또 다른
시작하다
MessagedLg ( '파일 "' + sr.name + '"는 유효한 플러그인이 아닙니다.',
mtinformation, [mbok], 0);
끝;
끝
또 다른
MessagedLg ( '플러그인을로드하는 오류가 발생했습니다 "' +
sr.name + ' ".', Mterror, [mbok], 0);
끝;
LoadPlugin 방법은 플러그인 메커니즘의 핵심을 보여줍니다. 먼저 플러그인은 DLL으로 작성되었습니다. 둘째, LoadLibrary API를 통해 동적으로로드됩니다. DLL이로드되면 포함 된 절차 및 기능에 액세스 할 수있는 방법이 필요합니다. API 호출 GetProcadDress는이 메커니즘을 제공하여 필요한 루틴에 대한 포인터를 반환합니다. 간단한 데모에서 플러그인에는 Constant Cplugin_Describe에 의해 지정된 SpectionPlugin이라는 절차 만 포함되어 있습니다 (절차 이름의 경우는 매우 중요하며 GetProcadDress로 전달 된 이름은 DLL에 포함 된 일상적인 이름과 정확히 동일해야합니다). . DLL에 요청 된 루틴이없는 경우 GetProcaddree는 NIL을 반환하므로 지정된 기능을 사용하여 리턴 값을 결정하는 데 동의합니다.
포인터를 사용하기 쉬운 방식으로 함수에 저장하려면 사용 된 변수의 특정 유형을 만들어야합니다. getProcadDress의 반환 값은 변수, SELFICEPROC에 저장되며 tplugindescribe 유형에 속합니다. 다음은 다음과 같습니다.
유형
tplugindescribe = 절차 (var desc : stdcall);
절차가 DLL 내부에 존재하므로 표준 통화 전환을 통해 모든 내보내기 루틴을 컴파일하므로 STDCALL 표시기가 필요합니다. 이 프로세스는 프로세스가 반환 될 때 플러그인 설명을 포함하는 Var 매개 변수를 사용합니다.
방금 얻은 프로세스를 호출하려면 주소를 프로세스 이름으로 저장하는 변수를 사용하고 매개 변수를 사용하십시오. 우리의 경우, 진술 :
DescriptionProc (설명)
플러그인에서 얻은 설명 프로세스가 호출되고 설명 변수는 플러그인의 기능을 설명하는 문자열로 채워집니다.
건설 플러그인
부모 응용 프로그램을 만들었으며 이제로드하려는 플러그인을 만들 시간입니다. 플러그인 파일은 표준 Delphi DLL이므로 Delphi IDE에서 새로운 DLL 프로젝트를 작성하여 저장합니다. 내보낸 플러그인 함수는 문자열 매개 변수를 사용하므로 Sharemen 장치는 프로젝트의 사용 절에 먼저 배치되어야합니다. 그림 4는 간단한 플러그인의 프로젝트 소스 파일을 나열합니다.
용도
Sharemem, Sysutils, 클래스,
'main.pas'의 메인;
{$ e plg.}
수출
SpectionPlugin;
시작하다
끝.
플러그인은 DLL 파일이지만 .dll 확장자를 제공 할 필요는 없습니다. 실제로, 한 가지 이유는 우리에게 확장을 변경 해야하는 이유가 충분합니다. 상위 응용 프로그램이 파일을로드 할 것을 찾으면 새 확장자가 특정 파일 마스크 역할을 할 수 있습니다. 다른 확장자 (예제는 *.plg를 사용)를 사용하면 응용 프로그램이 해당 파일 만로드 할 것이라고 확신 할 수 있습니다. 컴파일 표시기 $ x는이 변경을 달성하거나 프로젝트 옵션 대화 상자의 응용 프로그램 페이지를 통해 확장을 설정할 수 있습니다.
첫 번째 예제 플러그인의 코드는 매우 간단합니다. 그림 5는 새 장치에 포함 된 코드를 보여줍니다. SpectionPlugin 프로토 타입은 Shell 응용 프로그램의 Tplugindescribe 유형과 일치하며 추가 내보내기 예약 된 단어를 사용하여 프로세스가 내보내도록 지정합니다. 내보낸 프로세스 이름은 메인 프로젝트 소스 코드의 내보내기 섹션에도 나타납니다 (그림 4에 나열).
단위 메인;
인터페이스
절차 spectionplugin (var desc : string);
수출;
구현
절차 spectionplugin (var desc : string);
시작하다
DESC : = '테스트 플러그인 v1.00';
끝;
끝.
이 플러그인을 테스트하기 전에 주 응용 프로그램의 경로로 복사하십시오. 가장 쉬운 방법은 홈 디렉토리의 하위 디렉토리에 플러그인을 작성한 다음 출력 경로를 기본 경로로 설정하는 것입니다 (프로젝트 옵션 대화 상자의 디렉토리/조건부 도이 설정에도 사용할 수 있음).
디버그
이제 Delphi 3 : IDE에서 DLL을 디버그하는 기능을 소개하겠습니다. DLL 프로젝트에서는 RUN 매개 변수 대화 상자를 통해 호스트 애플리케이션으로 프로그램을 지정할 수 있습니다. 그런 다음 DLL 코드에서 중단 점을 설정하고 F9를 눌러 일반 응용 프로그램에서하는 것처럼 실행할 수 있습니다. Delphi는 지정된 호스트 프로그램을 실행하고 DLL을 디버그 정보로 컴파일하여 DLL 코드의 중단 점으로 안내합니다.