Delphi Programming Forum
C++Builder  |  Delphi  |  FireMonkey  |  C/C++  |  Free Pascal  |  Firebird
볼랜드포럼 BorlandForum
 경고! 게시물 작성자의 사전 허락없는 메일주소 추출행위 절대 금지
델파이 포럼
Q & A
FAQ
팁&트릭
강좌/문서
자료실
컴포넌트/라이브러리
FreePascal/Lazarus
볼랜드포럼 홈
헤드라인 뉴스
IT 뉴스
공지사항
자유게시판
해피 브레이크
공동 프로젝트
구인/구직
회원 장터
건의사항
운영진 게시판
회원 메뉴
북마크
델마당
볼랜드포럼 광고 모집

델파이 Q&A
Delphi Programming Q&A
[10961] Re:Re:[감사] MDIchild를 DLL로 구성하고 ODAC 이용하는 문제발생
도랑치기 [] 1618 읽음    2006-10-02 09:05
답변감사합니다
bpl로 함 해봐야 겠네요...

박지훈.임프 님이 쓰신 글 :
: ODAC를 써본 적이 없어서 확실하게 답변을 드리기는 어렵지만.. 좀 의심이 가는 부분만 말씀드리지요.
: 폼들을 dll로 만들어 올렸을 경우, ODAC처럼 폼들에서 참조되는 라이브러리들은 어떻게 처리하셨나요?
: ODAC를 패키지(bpl)로 런타임 패키지로 불러들였든 혹은 정적으로 링크시켰든 문제의 소지가 있습니다.
:
: 기본적으로 dll로 만든 폼들 사이에서는 각각 VCL의 주소공간이 별도로 생성되므로, dll마다 별도의 ODAC 구현이 포함되어 있을 것입니다. 설사 ODAC bpl을 불러들이도록 했다고 해도 각 폼 dll들이 불러들인 ODAC 구현은 별도로 여러번 로딩될 것입니다.
:
: 여기까지는 ODAC 뿐만 아니라 어떤 라이브러리를 써도 마찬가지입니다. 문제는 이 다음부터입니다. 만약 ODAC라는 라이브러리가, 한 프로그램에서는 하나의 인스턴스만 실행되어야 한다는 것을 전제로 만들어졌다면 이런 상황에서는 문제가 생깁니다. 복잡한 컴포넌트 라이브러리라면 얼마든지 있을 수 있는 상황입니다.
:
: 문제가 발생한 원인이 이것 때문인지 아닌지 확실히 하실 필요가 있을테니, 문제가 생긴 폼을 dll이 아닌 별도의 exe로 만들어서 같은 방법으로 테스트해보시길 권해드립니다. 새 빈 프로젝트를 만들어서 거기에 해당 폼을 포함시키면 간단히 테스트할 수 있겠지요.
:
: 만약 문제가 이것 때문이라고 판단이 된다면, 해결책은 dll 폼을 쓰지 않는 것 뿐입니다. 그렇다고 반드시 전체를 하나의 exe로 뭉뚱그려 만들 필요는 없습니다. 더 권하고 싶은 방법은, 폼을 dll이 아닌 bpl로 나누는 것입니다. bpl로 만들어진 폼은 그 자신도 메인 exe의 VCL 주소 공간에 포함되고, 당연히 폼에서 사용한 다른 서드파티 컴포넌트도 마찬가지이므로 그런 문제는 발생하지 않습니다.
:
: 그럼...
:
:
: 도랑치기 님이 쓰신 글 :
: : 버전     : Delphi6
: : DBMS     : Oracle
: : 컴포넌트 : ODAC
: :
: : MDIChild방식으로 데이타모듈을 이용하여 ODAC 컴포넌트의 OraSession컴포넌트를 올려놓고 사용했습니다. 실행파일의 메인메뉴에서 메뉴를 클릭하여 Child폼(폼속성은 MDIChild로 지정)을 호출하는데 호출은 정상적으로 됩니다 그런데 자료를 조회하는 버튼을 여속적으로 10번을 클릭을 하면
: : Access Violation 에러가 발생합니다. 소스를 보시고 문제가 되는부분을 해결 부탁합니다.
: :
: : - 메인소스 -
: : unit Nis_Main;
: :
: : interface
: :
: : uses
: :   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
: :   Dialogs, Menus, ExtCtrls, DB, DBAccess, Ora, StdCtrls, psapi;
: :
: : type
: :   TNis_MainW = class(TForm)
: :     MainMenu1: TMainMenu;
: :     N1: TMenuItem;
: :     N2: TMenuItem;
: :     N3: TMenuItem;
: :     procedure FormClose(Sender: TObject; var Action: TCloseAction);
: :     procedure N2Click(Sender: TObject);
: :     procedure FormShow(Sender: TObject);
: :   private
: :     { Private declarations }
: :   public
: :     { Public declarations }
: :   end;
: :
: : type
: :   TCreateChildForm = procedure (MainApp : TApplication; exe_scr : Tscreen; GP_OraSession: TComponent; GPs_Dat : Array of PChar); stdcall;
: :
: : var
: :   Nis_MainW: TNis_MainW;
: :
: : implementation
: :
: : Uses
: :   Nis_Dm;
: :
: : {$R *.dfm}
: :
: : procedure TNis_MainW.FormClose(Sender: TObject; var Action: TCloseAction);
: : var
: :   i : integer ;
: : begin
: :   for i:=0 to Screen.FormCount - 1 do
: :   begin
: :     if Screen.Forms[i].Name <> 'Nis_MainW' then
: :       Screen.Forms[i].close ;
: :   end;
: :
: :   Nis_DmW.OraSession1.Disconnect;
: :   Action := caFree;
: : end;
: :
: : procedure TNis_MainW.N2Click(Sender: TObject);
: : var
: :   DllHandle        : THandle;
: :   ProcAddr         : Pointer;
: :   CreateChildForm : TCreateChildForm;
: :   i : Integer;
: :   Form: TForm;
: :   AControl: TControl;
: : begin
: :   for i:=0 to Screen.FormCount - 1 do
: :   begin
: :     if Screen.Forms[i].Name = 'wf_Lv1w' then
: :     begin
: :       Screen.Forms[i].BringToFront;
: :       exit;
: :     end;
: :   end;
: : 
: :   DllHandle := LoadLibrary(PChar('Lv1.dll'));
: :   if DllHandle > 32 then
: :   begin
: :     ProcAddr := GetProcAddress(DllHandle, 'CreateMDIChildForm');
: :
: :     if ProcAddr <> nil then
: :     begin
: :       CreateChildForm := ProcAddr;
: :       CreateChildForm(Application, Screen, Nis_DmW.OraSession1, ['11','12']);
: :     end;
: :   end;
: : end;
: :
: : procedure TNis_MainW.FormShow(Sender: TObject);
: : begin
: :   Nis_DmW.OraSession1.Connect;
: : end;
: :
: : end.
: :
: : - DLL 소스 -
: : library Lv1;
: :
: : uses
: :   SysUtils,
: :   Classes,
: :   Forms,
: :   Ora,
: :   wf_Lv1 in 'wf_Lv1.pas' {wf_Lv1w},
: :   Init in 'Init.pas';
: :
: : procedure CreateMDIChildForm(MainApp : TApplication; exe_scr : Tscreen; GP_OraSession: TComponent; GPs_Dat : Array of PChar); stdcall;
: : begin
: :   Application    := MainApp;
: :   Screen         := Exe_scr;
: :  
: :   if wf_Lv1w = nil then
: :   begin
: :     wf_Lv1w := Twf_Lv1w.Create(nil);
: :     wf_Lv1w.Edit1.Text := GPs_Dat[0];
: :     wf_Lv1w.Edit2.Text := GPs_Dat[1];
: :     wf_Lv1w.OraQuery1.Session := TOraSession(GP_OraSession);
: :     wf_Lv1w.Show;
: :   end;
: : end;
: :
: : exports
: :   CreateMDIChildForm;
: :
: : begin
: :
: : end.
: :
: : - DLL에 포함된 폼(wf_Lv1.pas) 소스 -
: : unit wf_Lv1;
: :
: : interface
: :
: : uses
: :   Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
: :   Dialogs, dxCntner, dxTL, dxDBCtrl, dxDBGrid, DB, MemDS, DBAccess, Ora,
: :   StdCtrls, dxDBTLCl, dxGrClms;
: :   
: : type
: :   Twf_Lv1w = class(TForm)
: :     Edit1: TEdit;
: :     Edit2: TEdit;
: :     Button1: TButton;
: :     Button2: TButton;
: :     Edit3: TEdit;
: :     Label1: TLabel;
: :     OraDataSource1: TOraDataSource;
: :     OraQuery1: TOraQuery;
: :     dxDBGrid1: TdxDBGrid;
: :     dxDBGrid1Column1: TdxDBGridColumn;
: :     OraQuery1LVY_KEY: TStringField;
: :     procedure Button1Click(Sender: TObject);
: :     procedure FormClose(Sender: TObject; var Action: TCloseAction);
: :     procedure FormShow(Sender: TObject);
: :     procedure dxDBGrid1DblClick(Sender: TObject);
: :     procedure Button2Click(Sender: TObject);
: :     procedure FormDestroy(Sender: TObject);
: :   private
: :     { Private declarations }
: :   public
: :     { Public declarations }
: :   end;
: :
: : var
: :   wf_Lv1w: Twf_Lv1w;
: :
: : implementation
: :
: : procedure ShowChildForm_Lv2(MainApp : TApplication; exe_scr : Tscreen; GP_OraSession: TComponent; GPs_Dat : Array of PChar); stdcall; external 'Lv2.dll'
: :
: :
: : {$R *.dfm}
: :
: : procedure Twf_Lv1w.Button1Click(Sender: TObject);
: : begin
: :   Label1.Caption := '';
: :   Label1.Refresh;
: :
: :   with OraQuery1 do
: :   try
: :     Close;
: :     Sql.Clear;
: :     Sql.Text := 'SELECT LVY_KEY FROM RISTNLVBOOK';
: :
: :     Label1.Caption := OraQuery1.Session.Username+','+OraQuery1.Session.Password+','+OraQuery1.Session.Server;
: :
: :     Open;
: :
: :     Edit3.Text := IntToStr(OraQuery1.RecordCount);
: :   except
: :     on E : Exception do
: :     begin
: :       Edit3.Text := '0';
: :       Application.MessageBox(Pchar(E.Message+#13#10+OraQuery1.Session.Username+','+OraQuery1.Session.Password+','+OraQuery1.Session.Server),
: :                              '확인',MB_OK);
: :     end;
: :   end;
: : end;
: :
: : procedure Twf_Lv1w.FormClose(Sender: TObject; var Action: TCloseAction);
: : begin
: :   Action := caFree;
: : end;
: :
: : procedure Twf_Lv1w.FormShow(Sender: TObject);
: : begin
: :   Left := 0;
: :   Top  := 0;
: : end;
: :
: : procedure Twf_Lv1w.dxDBGrid1DblClick(Sender: TObject);
: : begin
: :   ShowChildForm_Lv2(Application, Screen, OraQuery1, [PChar(OraQuery1.FieldByName('LVY_KEY').AsString)]);
: : end;
: :
: : procedure Twf_Lv1w.Button2Click(Sender: TObject);
: : begin
: :   if OraQuery1.Session.Connected then
: :     ShowMessage(OraQuery1.Session.Username+','+OraQuery1.Session.Password+','+OraQuery1.Session.Server)
: :   else
: :     ShowMessage('해제');
: : end;
: :
: : procedure Twf_Lv1w.FormDestroy(Sender: TObject);
: : begin
: :   wf_Lv1w := nil;
: : end;
: :
: : end.
: :
: : - DLL에 포함된 Init.pas 소스-
: : unit Init;
: :
: : interface
: :
: : Uses
: :   Forms;
: :
: : var
: :   DllApplication : TApplication;
: :   DllScreen      : TScreen;
: :
: : implementation
: :
: : initialization
: :   DllApplication := Application;
: :   DllScreen      := Screen;
: :
: : finalization
: :   Application := DllApplication;
: :   Screen      := DllScreen;
: : end.

+ -

관련 글 리스트
10957 [질문] MDIchild를 DLL로 구성하고 ODAC 이용하는 문제발생 도랑치기 2077 2006/09/29
10960     Re:[질문] MDIchild를 DLL로 구성하고 ODAC 이용하는 문제발생 박지훈.임프 1681 2006/09/30
10961         Re:Re:[감사] MDIchild를 DLL로 구성하고 ODAC 이용하는 문제발생 도랑치기 1618 2006/10/02
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.