자유롭게 질의 및 응답을 할 수 있는 게시판입니다. 개발자 여러분의 답변이 큰 도움이 됩니다.
- 제품설치/등록 오류 문의: 설치/등록 Q&A 이용 (제품 구매 고객 한정)
Delphi Access Violation at address 0040B508... 질문드립니다. ^^
2016.01.22 15:43
본 게시판 사용시 당부 사항
* 이 게시판은 자유롭게 질문을 올리고 자발적으로 답변을 공유하는 게시판입니다.
* 어느 누구도 답변을 달아야만 하는 책임은 없습니다.
* 따라서 질문을 올리실 때에는 최대한 자세하고 정중하게 질문을 올려 주세요.
* 최대한 질문을 자세히 올려야 답변도 자세히 올라 옵니다.
* 본 질문에 답변을 주시는 여러 개발자님들께 미리 감사드립니다.
-----------------------------------------------------------------------------------------------
안녕하세요.
데브기어 관리자님^^
다시 한번 더 질문을 드려 봅니다.
델파이7(window xp) 작업한 파일들(dll 포함)을 델파이xe5(window7 64bit)로 가져와서 마이그레이션 중에 있습니다.
로그인후 메인메뉴에 화면이 나옵니다.
현재 메인메뉴화면에서 A메뉴를 클릭하면 아래와 같은 에러가 나타납니다.
(클릭할려는 A메뉴부분 xe5에서 다시 컴파일한 DLL을 적용하였습니다.)
"Access Violation at address 0040B508 in module 'ATP2.exe'. Read of address 000003A8."
에러가 가리키는 부분은 uSubForm 소스상의 아래 부분인거 같은데
function TfmASubForm.FindCommand(CommandName: String): TCommand;
begin
Result:= CommandArray.FindCommand(CommandName);
If Result = Nil
Then Begin
ErrorCode:= -3;
// Command를 못찾더라도 Execute를 실행하는데 에러를 내지 않는다. 에러코드만 변경
Result:= FNilCommand;
End
Else ErrorCode:= 0;
end;
제 생각에는 유니코드와 관련이 있는거 같은데 자료를 봐도 잘 모르겠습니다.
string 을 AnsiString, WideString로 변경해서 해봐도 같은 에러가 나옵니다.
원인을 못찾겠습니다. (많이 헤매고 있습니다. 도와주세요^^)
질문이 길더라도 끝까지 읽어봐주시고 답변 꼭 부탁드리겠습니다. ^^
아래는 메인화면 메뉴 클릭시 소스와 uSubForm, CommandArray, RunDll 소스입니다.
---------------------------------------------------------------------------------------------------
1. 메인화면 메뉴 클릭시 소스
procedure TfmMain.cxGBmenuCellDblClick(Sender: TcxCustomGridTableView;
ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
AShift: TShiftState; var AHandled: Boolean);
var
ocxTabSheet : TcxTabSheet;
Command : TCommand;
fmSub : TfmASubForm;
begin
showmessage('1 >' + _AssGeneralID); ---값 잘가져옴---
_findModule := ap_ATPmainMenu.FieldByName('DLLname').AsString;
_findDllForm := ap_ATPmainMenu.FieldByName('menuMainForm').AsString;
showmessage('2 >' + _AssGeneralIP); ---값 잘가져옴---
INSERT_tbOG(_AssGeneralIP,_AssGeneralID,_AssGeneralPass,ACom,fmMain.acHeroKey,_comkey,0
,'주메뉴'
,fmMain.acHero + '->' + ap_ATPmainMenu.FieldByName('menuName').AsString
,'fmMain');
ocxTabSheet := TcxTabSheet(self.FindComponent(ap_ATPmainMenu.FieldByName('menuTabSheet').AsString));
cxPageControl1.ActivePage := ocxTabSheet;
showmessage('3 >' + IntToStr(ocxTabSheet.ControlCount)); ---값 잘가져옴---
if ocxTabSheet.ControlCount > 0
then exit;
fmMain.RunModule(_findDllForm, ExtractFilePath(ParamStr(0)) + _findModule + '.dll', ocxTabSheet, True);
showmessage('4 >' + _findDllForm); ---값 잘가져옴---
fmSub := fmMain.FindSubForm(_findDllForm);
showmessage('5 >'+_findDllForm); ---값 잘가져옴---
showmessage('6 >'+_findModule); ---값 잘가져옴---
Command := fmSub.FindCommand('용영'); -- 여기서 에러가 납니다.---
showmessage('7 >');
if Command = Nil then Exit;
Command.Params.Values['어디서'] := ' ' + ap_ATPmainMenu.FieldByName('menuName').AsString;
Command.Params.Values['탈부착'] := '부착';
Command.Params.Values['Hero'] := fmMain.acHero;
Command.Params.Values['HeroName'] := fmMain.acHeroName;
Command.Params.Values['HeroKey'] := IntToStr(fmMain.acHeroKey);
Command.Params.Values['ReBBB'] := fmMain.acReBBB;
Command.Params.Values['ReSSO'] := fmMain.acReSSO;
Command.Params.Values['ReWeA'] := fmMain.acReWeA;
Command.Params.Values['WeA'] := fmMain.acWeA;
Command.Params.Values['real_big'] := fmMain.acReal_big;
Command.Params.Values['real_sm'] := fmMain.acReal_sm;
Command.Params.Values['weName'] := fmMain.acweName;
Command.Params.Values['Tissue'] := IntToStr(fmMain.acTissue);
Command.Params.Values['TissueName'] := _acTissueName;
Command.Params.Values['Platoon'] := IntToStr(fmMain.acPlatoon);
Command.Params.Values['PlatoonName'] := fmMain.acPlatoonName;
Command.Params.Values['Niche'] := IntToStr(fmMain.acNiche);
Command.Params.Values['Right'] := fmMain.acManWork;
Command.Params.Values['accessDate'] := DateToStr(fmMain.acDate);
Command.Params.Values['HeroAffair'] := fmMain.acHeroAffair;
Command.Params.Values['posiName'] := fmMain.acposiName;
Command.Params.Values['_comKey'] := IntToStr(_comKey);
Command.Params.Values['AssGeneralIP'] := _AssGeneralIP;
Command.Params.Values['AssGeneralID'] := _AssGeneralID;
Command.Params.Values['AssGeneralPass'] := _AssGeneralPass;
Command.Params.Values['ftpHost'] := _ftpHost;
Command.Params.Values['ftpUsername'] := _ftpUsername;
Command.Params.Values['ftpPassword'] := _ftpPassword;
Command.Params.Values['encryptID'] := _encryptID;
Command.Params.Values['encryptPASS'] := _encryptPASS;
Command.Execute;
showmessage('cxPageControl1.ActivePage.Caption = ' + cxPageControl1.ActivePage.Caption);
end;
---------------------------------------------------------------------------------------------------
2. uSubForm 소스
unit uSubForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, CommandArray, StdCtrls, RunDLL, ExtCtrls, ADODB, DB,
ComCtrls, Menus, XiButton;
type
TfmASubForm = class(TForm)
CommandArray: TCommandArray;
XiButton_SunFormclose: TXiButton;
procedure XiButton_SunFormcloseClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
ModuleID : WideString;
ErrorCode : Integer;
Function MainModule:TfmASubForm;
Function MainCommand(CommandName:String):TCommand;
Function FindSubForm(ModuleID:WideString):TfmASubForm;
Function FindCommand(CommandName:String):TCommand;
Function GetCommand(ModuleID:WideString;CommandName:String):TCommand;
Procedure RunModule(ModuleID,DllName:WideString; Parent:TwinControl; Visible:Boolean);
procedure SubFormOpen(ModuleName,FormName, AdhereYN, Bigo : String
; Parent:TwinControl; Visible:Boolean ; _SerialKey : Integer
; ADODataSet : TDataSet ; QueryCheck : Boolean);
Procedure CloseModules(MainForm:TForm);
procedure StartForm(fmfm : TForm ; fCommand: TCommand ; Adhere : WideString);
published
myDataSet : TDataSet;
end;
var
fmASubForm: TfmASubForm;
implementation
///uses DBConn, Disk, inSide;
var
FNilCommand : TCommand;
{$R *.dfm}
{ TfmASubForm }
function TfmASubForm.FindSubForm(ModuleID:WideString): TfmASubForm;
var
Loop : Integer;
begin
ErrorCode:= -2;
Result:= Nil;
For Loop:= 0 to Application.ComponentCount-1
do Begin
If Application.Components[Loop] is TfmASubForm
then Begin
If UPPERCASE(Application.Components[Loop].Name) = UPPERCASE(ModuleID)
then
Try
ErrorCode:= 0;
Result:= TfmASubForm(Application.Components[Loop]);
Break;
Except
End;
End;
End;
end;
procedure TfmASubForm.RunModule(ModuleID,DllName:WideString; Parent:TwinControl; Visible:Boolean);
begin
TRunDLL.Run(ModuleID, DllName, Parent, Visible);
end;
procedure TfmASubForm.SubFormOpen(ModuleName,FormName,AdhereYN, Bigo : String
; Parent:TwinControl; Visible:Boolean ; _SerialKey : Integer
; ADODataSet : TDataSet ; QueryCheck : Boolean);
var mainCommand, SubCommand : TCommand;
fmMain, fmSub : TfmASubForm;
f : Integer;
begin
fmMain := Self;
mainCommand := fmMain.FindCommand('용영');
self.RunModule(ModuleName, ExtractFilePath(ParamStr(0)) + ModuleName + '.dll', Parent, Visible);
Try
fmSub := Self.FindSubForm(FormName); //ModuleName);
If fmSub = Nil then Exit;
SubCommand := fmSub.FindCommand('용영');
if SubCommand = Nil then Exit;
SubCommand.Params.Values['어디서'] := Self.ModuleID;
SubCommand.Params.Values['탈부착'] := AdhereYN;
SubCommand.Params.Values['비고'] := Bigo;
SubCommand.Params.Values['Hero'] := Self.FindCommand('용영').Params.Values['Hero']; //Self.Hint;
SubCommand.Params.Values['HeroPower'] := Self.FindCommand('용영').Params.Values['HeroPower']; //Self.Hint;
SubCommand.Params.Values['HeroKey'] := Self.FindCommand('용영').Params.Values['HeroKey']; // 접속자사번
SubCommand.Params.Values['Tissue'] := Self.FindCommand('용영').Params.Values['Tissue']; //접속자법인
SubCommand.Params.Values['Platoon'] := Self.FindCommand('용영').Params.Values['Platoon'];
SubCommand.Params.Values['Niche'] := Self.FindCommand('용영').Params.Values['Niche'];
SubCommand.Params.Values['accessDate'] := Self.FindCommand('용영').Params.Values['accessDate']; // 접속일
SubCommand.Params.Values['HeroAffair'] := Self.FindCommand('용영').Params.Values['HeroAffair'];
SubCommand.Params.Values['reBBB'] := Self.FindCommand('용영').Params.Values['reBBB'];
SubCommand.Params.Values['reSSO'] := Self.FindCommand('용영').Params.Values['reSSO'];
SubCommand.Params.Values['asshk'] := Self.FindCommand('용영').Params.Values['asshk']; // 접속자사번
SubCommand.Params.Values['asshr'] := Self.FindCommand('용영').Params.Values['Hero']; // 접속자
SubCommand.Params.Values['asspl'] := Self.FindCommand('용영').Params.Values['asspl']; //접속자사업소번
SubCommand.Params.Values['asspn'] := Self.FindCommand('용영').Params.Values['asspn']; // 접속자사업소
SubCommand.Params.Values['assni'] := Self.FindCommand('용영').Params.Values['assni']; // 접속자부서
SubCommand.Params.Values['assaff'] := Self.FindCommand('용영').Params.Values['assaff']; // 접속자권한
SubCommand.Params.Values['SerialKey'] := IntToStr(_SerialKey);
SubCommand.Params.Values['AssGeneralIP'] := Self.FindCommand('용영').Params.Values['AssGeneralIP'];
SubCommand.Params.Values['AssGeneralID'] := Self.FindCommand('용영').Params.Values['AssGeneralID'];
SubCommand.Params.Values['AssGeneralPass'] := Self.FindCommand('용영').Params.Values['AssGeneralPass'];
SubCommand.Params.Values['ftpHost'] := Self.FindCommand('용영').Params.Values['ftpHost'];
SubCommand.Params.Values['ftpUsername'] := Self.FindCommand('용영').Params.Values['ftpUsername'];
SubCommand.Params.Values['ftpPassword'] := Self.FindCommand('용영').Params.Values['ftpPassword'];
SubCommand.Execute;
/// 모듈종료시부터 ★★★★★★★★★★★★★★★★
mainCommand := fmMain.FindCommand('용영');
Finally
if fmSub = Nil then fmSub.Free;
End;
end;
function TfmASubForm.FindCommand(CommandName: String): TCommand;
begin
showmessage('uSubform 1' + CommandName); -- 값 잘가져옴
Result:= CommandArray.FindCommand(CommandName);
showmessage('uSubform 2' + CommandName); -- 값 잘가져옴
If Result = Nil
Then Begin
ErrorCode:= -3;
// Command를 못찾더라도 Execute를 실행하는데 에러를 내지 않는다. 에러코드만 변경
Result:= FNilCommand;
End
Else ErrorCode:= 0;
end;
function TfmASubForm.GetCommand(ModuleID:WideString; CommandName: String): TCommand;
var
fmSub : TfmASubForm;
begin
fmSub:= FindSubForm(ModuleID);
If fmSub = Nil then Begin
Result:= FNilCommand;
Exit;
End;
Result:= fmSub.FindCommand(CommandName);
end;
function TfmASubForm.MainModule: TfmASubForm;
begin
ErrorCode:= 0;
Result:= TfmASubForm(Application.MainForm)
end;
function TfmASubForm.MainCommand(CommandName: String): TCommand;
begin
If MainModule = Nil then Result:= FNilCommand
Else Result:= MainModule.FindCommand(CommandName);
end;
procedure TfmASubForm.CloseModules(MainForm: TForm);
var
Loop : Integer;
begin
For Loop:= 0 to Application.ComponentCount-1
do Begin
If not (Application.Components[Loop] is TForm) then Continue;
If Application.Components[Loop] = MainForm then Continue;
TForm(Application.Components[Loop]).Close;
End;
end;
procedure TfmASubForm.StartForm(fmfm : TForm ; fCommand: TCommand ; Adhere : WideString);
var bFound : Boolean;
f,tiNum,niNum : Integer;
begin
if Adhere = '부착'
then begin
fmfm.BorderStyle := bsNone;
fmfm.Align:= alClient;
end
else begin
fmfm.BorderStyle := bsSizeable;
fmfm.Align:= alNone;
ShowModal;
end;
end;
procedure TfmASubForm.XiButton_SunFormcloseClick(Sender: TObject);
begin
close;
end;
procedure TfmASubForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
initialization
FNilCommand:= TCommand.Create(Nil);
finalization
FreeAndNil(FNilCommand);
end.
---------------------------------------------------------------------------------------------------
3. CommandArray 소스
unit CommandArray;
interface
uses
SysUtils, Classes;
type
TCommand = class;
TCommands = class;
TCommandArray = class;
TCommandEvent = procedure(Command:TCommand; Params:TStringList) of object;
TCommand = class(TCollectionItem)
private
FName, FCommandName : String;
FOnExecute : TCommandEvent;
FCommandKind: Integer;
protected
CommandArray : TCommandArray;
function GetDisplayName:String; override;
procedure SetIndex(Index:Integer); override;
public
Data : Pointer;
Params : TStringList;
constructor Create(AOwner:TCollection); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
function GetNamePath: String; override;
Procedure Execute;
published
property CommandName : String read FCommandName write FCommandName;
property CommandKind : Integer read FCommandKind write FCommandKind;
property Name : String read FName write FName;
property OnExecute : TCommandEvent read FOnExecute write FOnExecute;
end;
TCommands = class(TCollection)
private
function GetItem(Index:Integer): TCommand;
procedure SetItem(Index:Integer; Item:TCommand);
protected
//procedure SetItemName(Item: TCollectionItem); override;
public
Owner : TComponent;
constructor Create(AOwner: TComponent);
function Add: TCommand;
function GetOwner: TPersistent; override;
property Items[Index:Integer] : TCommand read GetItem write SetItem; default;
end;
TCommandArray = class(TComponent)
private
{ Private declarations }
FCommands : TCommands;
protected
{ Protected declarations }
public
{ Public declarations }
Constructor Create(AOwner:TComponent); override;
Destructor Destroy; override;
Function FindCommand(CommandName:String):TCommand; overload;
Function FindCommand(CommandKind:Integer):TCommand; overload;
procedure InternalAddItem;
procedure InternalMoveItem(FromIndex,ToIndex:Integer);
procedure InternalDeleteItem(Index:Integer);
published
{ Published declarations }
Property Commands : TCommands read FCommands write FCommands;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Ryu Command', [TCommandArray]);
end;
{ TCommand }
procedure TCommand.Assign(Source: TPersistent);
var
Item : TCommand;
begin
if Source is TCommand then begin
Item:= TCommand(Source);
CommandName:= Item.CommandName;
Name:= Item.Name;
end;
end;
constructor TCommand.Create(AOwner: TCollection);
begin
inherited Create(AOwner);
Params:= TStringList.Create;
If AOwner <> Nil then CommandArray:= TCommandArray(TCommands(AOwner).Owner);
FName := ClassName + IntToStr(ID);
end;
destructor TCommand.Destroy;
begin
Params.Free;
inherited;
end;
procedure TCommand.SetIndex(Index: Integer);
var
IndexFrom, IndexTo: integer;
begin
if csDestroying in CommandArray.ComponentState then Exit;
IndexFrom:= Index;
inherited SetIndex(Index);
IndexTo:= Index;
if IndexFrom <> IndexTo then
CommandArray.InternalMoveItem(IndexFrom, IndexTo);
end;
function TCommand.GetDisplayName: String;
begin
result := FName;
if result = '' then result := inherited GetDisplayName;
end;
function TCommand.GetNamePath: String;
begin
if Collection <> nil then
Result := Collection.GetNamePath + FName
else
Result := inherited GetNamePath;
end;
procedure TCommand.Execute;
begin
If Assigned(FOnExecute) = True then FOnExecute(Self, Params);
end;
{ TCommands }
function TCommands.Add: TCommand;
begin
Result:= TCommand(inherited Add);
end;
constructor TCommands.Create(AOwner: TComponent);
begin
inherited Create(TCommand);
Owner:= AOwner;
end;
function TCommands.GetItem(Index: Integer): TCommand;
begin
Result:= TCommand(inherited GetItem(Index));
end;
procedure TCommands.SetItem(Index: Integer; Item: TCommand);
begin
inherited SetItem(Index, Item);
end;
function TCommands.GetOwner: TPersistent;
begin
result := Owner;
end;
{ TCommandArray }
constructor TCommandArray.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCommands:= TCommands.Create(Self);
end;
destructor TCommandArray.Destroy;
begin
FCommands.Free;
inherited;
end;
function TCommandArray.FindCommand(CommandName: String): TCommand;
var
Loop : Integer;
begin
Result:= Nil;
For Loop:= 0 to FCommands.Count-1 do Begin
If LowerCase(FCommands.Items[Loop].CommandName) = LowerCase(CommandName) then Begin
Result:= FCommands.Items[Loop];
Break;
End;
End;
end;
function TCommandArray.FindCommand(CommandKind: Integer): TCommand;
var
Loop : Integer;
begin
Result:= Nil;
For Loop:= 0 to FCommands.Count-1 do Begin
If FCommands.Items[Loop].CommandKind = CommandKind then Begin
Result:= FCommands.Items[Loop];
Break;
End;
End;
end;
procedure TCommandArray.InternalAddItem;
begin
end;
procedure TCommandArray.InternalDeleteItem(Index: Integer);
begin
end;
procedure TCommandArray.InternalMoveItem(FromIndex, ToIndex: Integer);
begin
end;
end.
---------------------------------------------------------------------------------------------------
4. RunDll 소스
unit RunDll;
interface
uses
Windows, SysUtils, Classes, Controls, Forms, Dialogs;
type
TRunDll = class(TObject)
private
{ Private declarations }
FList : TStringList;
Function LoadDll(DllName:WideString):Integer;
public
{ Public declarations }
Constructor Create;
Destructor Destroy; override;
class Procedure Run(ModuleID, DllName:WideString; Parent:TWinControl; Visible:Boolean);
End;
implementation
uses
uSubForm;
var
FRunDLL : TRunDLL = Nil;
Constructor TRunDll.Create;
Begin
Inherited Create;
FList:= TStringList.Create(true);
End;
Destructor TRunDll.Destroy;
Begin
FList.Free;
Inherited Destroy;
End;
Function TRunDll.LoadDll(DllName:WideString):Integer;
Begin
FList.Clear;
FList.Add(DllName);
FList.Values[DllName] := DllName;
Result:= StrToIntdef(FList.Values[DllName], -1);
If Result = -1
then Begin
Result := LoadLibrary(PWideChar(DllName));
showmessage('RunDll-6-LoadLibrary =>' + IntToStr(Result));
FList.Values[DllName]:= IntToStr(Result);
End;
End;
class Procedure TRunDll.Run(ModuleID, DllName:WideString; Parent:TWinControl; Visible:Boolean);
Var
iHandle : Integer;
DllFunc : Procedure (ModuleID:WideString; App:TApplication; Parent:TWinControl; Visible:Boolean); far;
Begin
If FRunDLL = Nil then FRunDLL:= TRunDLL.Create;
Try
iHandle := FRunDLL.LoadDll(DllName);
showmessage('DllName => ' + DllName + ' | iHandle =>' + IntToStr(iHandle));
If iHandle > 32
then Begin
//windows xp
// @DllFunc:= GetProcAddress(iHandle, PChar('OpenSubModule'));
// windows 7
@DllFunc:= GetProcAddress(iHandle, PWideChar('OpenSubModule'));
If @DllFunc <> Nil
then begin
DllFunc(ModuleID, Application, Parent, Visible);
end;
End;
Except
End;
End;
end.
-----------------------------------------------------------------------------------------
5.atp2.map 의 내용중 uSubForm 관련된 부분입니다.
Line numbers for uSubForm(uSubForm.pas) segment .text
67 0001:0027EAC8 68 0001:0027EAF8 69 0001:0027EB05 72 0001:0027EB0A
76 0001:0027EB2A 82 0001:0027EB4C 85 0001:0027EB8B 86 0001:0027EB99
87 0001:0027EBA4 88 0001:0027EBB6 90 0001:0027EBCD 93 0001:0027EBD2
71 0001:0027EBD5 95 0001:0027EBDE 99 0001:0027EC14 100 0001:0027EC41
101 0001:0027EC59 111 0001:0027EC84 116 0001:0027ECD0 118 0001:0027ECD6
127 0001:0027ECE6 129 0001:0027ED41 130 0001:0027ED4F 133 0001:0027ED68
135 0001:0027ED78 136 0001:0027ED88 141 0001:0027ED98 142 0001:0027EDBC
143 0001:0027EDCF 144 0001:0027EDE2 145 0001:0027EE12 146 0001:0027EE42
147 0001:0027EE72 148 0001:0027EEA2 149 0001:0027EED2 150 0001:0027EF02
151 0001:0027EF32 152 0001:0027EF62 153 0001:0027EF92 155 0001:0027EFC2
156 0001:0027EFF2 157 0001:0027F022 158 0001:0027F052 159 0001:0027F082
160 0001:0027F0B2 161 0001:0027F0E2 163 0001:0027F100 164 0001:0027F136
165 0001:0027F16C 166 0001:0027F1A2 167 0001:0027F1D8 168 0001:0027F20E
170 0001:0027F244 175 0001:0027F24C 198 0001:0027F269 201 0001:0027F27F
205 0001:0027F600 206 0001:0027F622 208 0001:0027F636 210 0001:0027F63C
212 0001:0027F649 214 0001:0027F653 215 0001:0027F65E 221 0001:0027F684
222 0001:0027F6B1 223 0001:0027F6BF 224 0001:0027F6C5 225 0001:0027F6CD
228 0001:0027F6CF 229 0001:0027F6DD 232 0001:0027F70C 233 0001:0027F715
234 0001:0027F720 235 0001:0027F72D 238 0001:0027F734 239 0001:0027F756
240 0001:0027F76C 241 0001:0027F77F 246 0001:0027F7A4 249 0001:0027F7B0
250 0001:0027F7CC 251 0001:0027F7EA 253 0001:0027F7FE 254 0001:0027F812
248 0001:0027F815 255 0001:0027F81A 261 0001:0027F820 263 0001:0027F845
265 0001:0027F854 266 0001:0027F85E 269 0001:0027F86A 270 0001:0027F874
271 0001:0027F87E 284 0001:0027F889 289 0001:0027F8C0 290 0001:0027F8CC
291 0001:0027F8D4 294 0001:0027F8D8 295 0001:0027F8E7 296 0001:0027F8ED
302 0001:0027F8F4 303 0001:0027F909
Line numbers for uSubForm(uSubForm.pas) segment .itext
298 0002:000015F8 299 0002:00001604 301 0002:00001617
-----------------------------------------------------------------------------------------
읽어주셔서 감사합니다.
답변 꼭 부탁드리겠습니다. ^^
Delphi Access Violation at address 0040B508... 질문드립니다. ^^
2016.01.22 15:43
본 게시판 사용시 당부 사항
* 이 게시판은 자유롭게 질문을 올리고 자발적으로 답변을 공유하는 게시판입니다.
* 어느 누구도 답변을 달아야만 하는 책임은 없습니다.
* 따라서 질문을 올리실 때에는 최대한 자세하고 정중하게 질문을 올려 주세요.
* 최대한 질문을 자세히 올려야 답변도 자세히 올라 옵니다.
* 본 질문에 답변을 주시는 여러 개발자님들께 미리 감사드립니다.
-----------------------------------------------------------------------------------------------
안녕하세요.
데브기어 관리자님^^
다시 한번 더 질문을 드려 봅니다.
델파이7(window xp) 작업한 파일들(dll 포함)을 델파이xe5(window7 64bit)로 가져와서 마이그레이션 중에 있습니다.
로그인후 메인메뉴에 화면이 나옵니다.
현재 메인메뉴화면에서 A메뉴를 클릭하면 아래와 같은 에러가 나타납니다.
(클릭할려는 A메뉴부분 xe5에서 다시 컴파일한 DLL을 적용하였습니다.)
"Access Violation at address 0040B508 in module 'ATP2.exe'. Read of address 000003A8."
에러가 가리키는 부분은 uSubForm 소스상의 아래 부분인거 같은데
function TfmASubForm.FindCommand(CommandName: String): TCommand;
begin
Result:= CommandArray.FindCommand(CommandName);
If Result = Nil
Then Begin
ErrorCode:= -3;
// Command를 못찾더라도 Execute를 실행하는데 에러를 내지 않는다. 에러코드만 변경
Result:= FNilCommand;
End
Else ErrorCode:= 0;
end;
제 생각에는 유니코드와 관련이 있는거 같은데 자료를 봐도 잘 모르겠습니다.
string 을 AnsiString, WideString로 변경해서 해봐도 같은 에러가 나옵니다.
원인을 못찾겠습니다. (많이 헤매고 있습니다. 도와주세요^^)
질문이 길더라도 끝까지 읽어봐주시고 답변 꼭 부탁드리겠습니다. ^^
아래는 메인화면 메뉴 클릭시 소스와 uSubForm, CommandArray, RunDll 소스입니다.
---------------------------------------------------------------------------------------------------
1. 메인화면 메뉴 클릭시 소스
procedure TfmMain.cxGBmenuCellDblClick(Sender: TcxCustomGridTableView;
ACellViewInfo: TcxGridTableDataCellViewInfo; AButton: TMouseButton;
AShift: TShiftState; var AHandled: Boolean);
var
ocxTabSheet : TcxTabSheet;
Command : TCommand;
fmSub : TfmASubForm;
begin
showmessage('1 >' + _AssGeneralID); ---값 잘가져옴---
_findModule := ap_ATPmainMenu.FieldByName('DLLname').AsString;
_findDllForm := ap_ATPmainMenu.FieldByName('menuMainForm').AsString;
showmessage('2 >' + _AssGeneralIP); ---값 잘가져옴---
INSERT_tbOG(_AssGeneralIP,_AssGeneralID,_AssGeneralPass,ACom,fmMain.acHeroKey,_comkey,0
,'주메뉴'
,fmMain.acHero + '->' + ap_ATPmainMenu.FieldByName('menuName').AsString
,'fmMain');
ocxTabSheet := TcxTabSheet(self.FindComponent(ap_ATPmainMenu.FieldByName('menuTabSheet').AsString));
cxPageControl1.ActivePage := ocxTabSheet;
showmessage('3 >' + IntToStr(ocxTabSheet.ControlCount)); ---값 잘가져옴---
if ocxTabSheet.ControlCount > 0
then exit;
fmMain.RunModule(_findDllForm, ExtractFilePath(ParamStr(0)) + _findModule + '.dll', ocxTabSheet, True);
showmessage('4 >' + _findDllForm); ---값 잘가져옴---
fmSub := fmMain.FindSubForm(_findDllForm);
showmessage('5 >'+_findDllForm); ---값 잘가져옴---
showmessage('6 >'+_findModule); ---값 잘가져옴---
Command := fmSub.FindCommand('용영'); -- 여기서 에러가 납니다.---
showmessage('7 >');
if Command = Nil then Exit;
Command.Params.Values['어디서'] := ' ' + ap_ATPmainMenu.FieldByName('menuName').AsString;
Command.Params.Values['탈부착'] := '부착';
Command.Params.Values['Hero'] := fmMain.acHero;
Command.Params.Values['HeroName'] := fmMain.acHeroName;
Command.Params.Values['HeroKey'] := IntToStr(fmMain.acHeroKey);
Command.Params.Values['ReBBB'] := fmMain.acReBBB;
Command.Params.Values['ReSSO'] := fmMain.acReSSO;
Command.Params.Values['ReWeA'] := fmMain.acReWeA;
Command.Params.Values['WeA'] := fmMain.acWeA;
Command.Params.Values['real_big'] := fmMain.acReal_big;
Command.Params.Values['real_sm'] := fmMain.acReal_sm;
Command.Params.Values['weName'] := fmMain.acweName;
Command.Params.Values['Tissue'] := IntToStr(fmMain.acTissue);
Command.Params.Values['TissueName'] := _acTissueName;
Command.Params.Values['Platoon'] := IntToStr(fmMain.acPlatoon);
Command.Params.Values['PlatoonName'] := fmMain.acPlatoonName;
Command.Params.Values['Niche'] := IntToStr(fmMain.acNiche);
Command.Params.Values['Right'] := fmMain.acManWork;
Command.Params.Values['accessDate'] := DateToStr(fmMain.acDate);
Command.Params.Values['HeroAffair'] := fmMain.acHeroAffair;
Command.Params.Values['posiName'] := fmMain.acposiName;
Command.Params.Values['_comKey'] := IntToStr(_comKey);
Command.Params.Values['AssGeneralIP'] := _AssGeneralIP;
Command.Params.Values['AssGeneralID'] := _AssGeneralID;
Command.Params.Values['AssGeneralPass'] := _AssGeneralPass;
Command.Params.Values['ftpHost'] := _ftpHost;
Command.Params.Values['ftpUsername'] := _ftpUsername;
Command.Params.Values['ftpPassword'] := _ftpPassword;
Command.Params.Values['encryptID'] := _encryptID;
Command.Params.Values['encryptPASS'] := _encryptPASS;
Command.Execute;
showmessage('cxPageControl1.ActivePage.Caption = ' + cxPageControl1.ActivePage.Caption);
end;
---------------------------------------------------------------------------------------------------
2. uSubForm 소스
unit uSubForm;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, CommandArray, StdCtrls, RunDLL, ExtCtrls, ADODB, DB,
ComCtrls, Menus, XiButton;
type
TfmASubForm = class(TForm)
CommandArray: TCommandArray;
XiButton_SunFormclose: TXiButton;
procedure XiButton_SunFormcloseClick(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
protected
{ Protected declarations }
public
{ Public declarations }
ModuleID : WideString;
ErrorCode : Integer;
Function MainModule:TfmASubForm;
Function MainCommand(CommandName:String):TCommand;
Function FindSubForm(ModuleID:WideString):TfmASubForm;
Function FindCommand(CommandName:String):TCommand;
Function GetCommand(ModuleID:WideString;CommandName:String):TCommand;
Procedure RunModule(ModuleID,DllName:WideString; Parent:TwinControl; Visible:Boolean);
procedure SubFormOpen(ModuleName,FormName, AdhereYN, Bigo : String
; Parent:TwinControl; Visible:Boolean ; _SerialKey : Integer
; ADODataSet : TDataSet ; QueryCheck : Boolean);
Procedure CloseModules(MainForm:TForm);
procedure StartForm(fmfm : TForm ; fCommand: TCommand ; Adhere : WideString);
published
myDataSet : TDataSet;
end;
var
fmASubForm: TfmASubForm;
implementation
///uses DBConn, Disk, inSide;
var
FNilCommand : TCommand;
{$R *.dfm}
{ TfmASubForm }
function TfmASubForm.FindSubForm(ModuleID:WideString): TfmASubForm;
var
Loop : Integer;
begin
ErrorCode:= -2;
Result:= Nil;
For Loop:= 0 to Application.ComponentCount-1
do Begin
If Application.Components[Loop] is TfmASubForm
then Begin
If UPPERCASE(Application.Components[Loop].Name) = UPPERCASE(ModuleID)
then
Try
ErrorCode:= 0;
Result:= TfmASubForm(Application.Components[Loop]);
Break;
Except
End;
End;
End;
end;
procedure TfmASubForm.RunModule(ModuleID,DllName:WideString; Parent:TwinControl; Visible:Boolean);
begin
TRunDLL.Run(ModuleID, DllName, Parent, Visible);
end;
procedure TfmASubForm.SubFormOpen(ModuleName,FormName,AdhereYN, Bigo : String
; Parent:TwinControl; Visible:Boolean ; _SerialKey : Integer
; ADODataSet : TDataSet ; QueryCheck : Boolean);
var mainCommand, SubCommand : TCommand;
fmMain, fmSub : TfmASubForm;
f : Integer;
begin
fmMain := Self;
mainCommand := fmMain.FindCommand('용영');
self.RunModule(ModuleName, ExtractFilePath(ParamStr(0)) + ModuleName + '.dll', Parent, Visible);
Try
fmSub := Self.FindSubForm(FormName); //ModuleName);
If fmSub = Nil then Exit;
SubCommand := fmSub.FindCommand('용영');
if SubCommand = Nil then Exit;
SubCommand.Params.Values['어디서'] := Self.ModuleID;
SubCommand.Params.Values['탈부착'] := AdhereYN;
SubCommand.Params.Values['비고'] := Bigo;
SubCommand.Params.Values['Hero'] := Self.FindCommand('용영').Params.Values['Hero']; //Self.Hint;
SubCommand.Params.Values['HeroPower'] := Self.FindCommand('용영').Params.Values['HeroPower']; //Self.Hint;
SubCommand.Params.Values['HeroKey'] := Self.FindCommand('용영').Params.Values['HeroKey']; // 접속자사번
SubCommand.Params.Values['Tissue'] := Self.FindCommand('용영').Params.Values['Tissue']; //접속자법인
SubCommand.Params.Values['Platoon'] := Self.FindCommand('용영').Params.Values['Platoon'];
SubCommand.Params.Values['Niche'] := Self.FindCommand('용영').Params.Values['Niche'];
SubCommand.Params.Values['accessDate'] := Self.FindCommand('용영').Params.Values['accessDate']; // 접속일
SubCommand.Params.Values['HeroAffair'] := Self.FindCommand('용영').Params.Values['HeroAffair'];
SubCommand.Params.Values['reBBB'] := Self.FindCommand('용영').Params.Values['reBBB'];
SubCommand.Params.Values['reSSO'] := Self.FindCommand('용영').Params.Values['reSSO'];
SubCommand.Params.Values['asshk'] := Self.FindCommand('용영').Params.Values['asshk']; // 접속자사번
SubCommand.Params.Values['asshr'] := Self.FindCommand('용영').Params.Values['Hero']; // 접속자
SubCommand.Params.Values['asspl'] := Self.FindCommand('용영').Params.Values['asspl']; //접속자사업소번
SubCommand.Params.Values['asspn'] := Self.FindCommand('용영').Params.Values['asspn']; // 접속자사업소
SubCommand.Params.Values['assni'] := Self.FindCommand('용영').Params.Values['assni']; // 접속자부서
SubCommand.Params.Values['assaff'] := Self.FindCommand('용영').Params.Values['assaff']; // 접속자권한
SubCommand.Params.Values['SerialKey'] := IntToStr(_SerialKey);
SubCommand.Params.Values['AssGeneralIP'] := Self.FindCommand('용영').Params.Values['AssGeneralIP'];
SubCommand.Params.Values['AssGeneralID'] := Self.FindCommand('용영').Params.Values['AssGeneralID'];
SubCommand.Params.Values['AssGeneralPass'] := Self.FindCommand('용영').Params.Values['AssGeneralPass'];
SubCommand.Params.Values['ftpHost'] := Self.FindCommand('용영').Params.Values['ftpHost'];
SubCommand.Params.Values['ftpUsername'] := Self.FindCommand('용영').Params.Values['ftpUsername'];
SubCommand.Params.Values['ftpPassword'] := Self.FindCommand('용영').Params.Values['ftpPassword'];
SubCommand.Execute;
/// 모듈종료시부터 ★★★★★★★★★★★★★★★★
mainCommand := fmMain.FindCommand('용영');
Finally
if fmSub = Nil then fmSub.Free;
End;
end;
function TfmASubForm.FindCommand(CommandName: String): TCommand;
begin
showmessage('uSubform 1' + CommandName); -- 값 잘가져옴
Result:= CommandArray.FindCommand(CommandName);
showmessage('uSubform 2' + CommandName); -- 값 잘가져옴
If Result = Nil
Then Begin
ErrorCode:= -3;
// Command를 못찾더라도 Execute를 실행하는데 에러를 내지 않는다. 에러코드만 변경
Result:= FNilCommand;
End
Else ErrorCode:= 0;
end;
function TfmASubForm.GetCommand(ModuleID:WideString; CommandName: String): TCommand;
var
fmSub : TfmASubForm;
begin
fmSub:= FindSubForm(ModuleID);
If fmSub = Nil then Begin
Result:= FNilCommand;
Exit;
End;
Result:= fmSub.FindCommand(CommandName);
end;
function TfmASubForm.MainModule: TfmASubForm;
begin
ErrorCode:= 0;
Result:= TfmASubForm(Application.MainForm)
end;
function TfmASubForm.MainCommand(CommandName: String): TCommand;
begin
If MainModule = Nil then Result:= FNilCommand
Else Result:= MainModule.FindCommand(CommandName);
end;
procedure TfmASubForm.CloseModules(MainForm: TForm);
var
Loop : Integer;
begin
For Loop:= 0 to Application.ComponentCount-1
do Begin
If not (Application.Components[Loop] is TForm) then Continue;
If Application.Components[Loop] = MainForm then Continue;
TForm(Application.Components[Loop]).Close;
End;
end;
procedure TfmASubForm.StartForm(fmfm : TForm ; fCommand: TCommand ; Adhere : WideString);
var bFound : Boolean;
f,tiNum,niNum : Integer;
begin
if Adhere = '부착'
then begin
fmfm.BorderStyle := bsNone;
fmfm.Align:= alClient;
end
else begin
fmfm.BorderStyle := bsSizeable;
fmfm.Align:= alNone;
ShowModal;
end;
end;
procedure TfmASubForm.XiButton_SunFormcloseClick(Sender: TObject);
begin
close;
end;
procedure TfmASubForm.FormClose(Sender: TObject; var Action: TCloseAction);
begin
Action := caFree;
end;
initialization
FNilCommand:= TCommand.Create(Nil);
finalization
FreeAndNil(FNilCommand);
end.
---------------------------------------------------------------------------------------------------
3. CommandArray 소스
unit CommandArray;
interface
uses
SysUtils, Classes;
type
TCommand = class;
TCommands = class;
TCommandArray = class;
TCommandEvent = procedure(Command:TCommand; Params:TStringList) of object;
TCommand = class(TCollectionItem)
private
FName, FCommandName : String;
FOnExecute : TCommandEvent;
FCommandKind: Integer;
protected
CommandArray : TCommandArray;
function GetDisplayName:String; override;
procedure SetIndex(Index:Integer); override;
public
Data : Pointer;
Params : TStringList;
constructor Create(AOwner:TCollection); override;
destructor Destroy; override;
procedure Assign(Source: TPersistent); override;
function GetNamePath: String; override;
Procedure Execute;
published
property CommandName : String read FCommandName write FCommandName;
property CommandKind : Integer read FCommandKind write FCommandKind;
property Name : String read FName write FName;
property OnExecute : TCommandEvent read FOnExecute write FOnExecute;
end;
TCommands = class(TCollection)
private
function GetItem(Index:Integer): TCommand;
procedure SetItem(Index:Integer; Item:TCommand);
protected
//procedure SetItemName(Item: TCollectionItem); override;
public
Owner : TComponent;
constructor Create(AOwner: TComponent);
function Add: TCommand;
function GetOwner: TPersistent; override;
property Items[Index:Integer] : TCommand read GetItem write SetItem; default;
end;
TCommandArray = class(TComponent)
private
{ Private declarations }
FCommands : TCommands;
protected
{ Protected declarations }
public
{ Public declarations }
Constructor Create(AOwner:TComponent); override;
Destructor Destroy; override;
Function FindCommand(CommandName:String):TCommand; overload;
Function FindCommand(CommandKind:Integer):TCommand; overload;
procedure InternalAddItem;
procedure InternalMoveItem(FromIndex,ToIndex:Integer);
procedure InternalDeleteItem(Index:Integer);
published
{ Published declarations }
Property Commands : TCommands read FCommands write FCommands;
end;
procedure Register;
implementation
procedure Register;
begin
RegisterComponents('Ryu Command', [TCommandArray]);
end;
{ TCommand }
procedure TCommand.Assign(Source: TPersistent);
var
Item : TCommand;
begin
if Source is TCommand then begin
Item:= TCommand(Source);
CommandName:= Item.CommandName;
Name:= Item.Name;
end;
end;
constructor TCommand.Create(AOwner: TCollection);
begin
inherited Create(AOwner);
Params:= TStringList.Create;
If AOwner <> Nil then CommandArray:= TCommandArray(TCommands(AOwner).Owner);
FName := ClassName + IntToStr(ID);
end;
destructor TCommand.Destroy;
begin
Params.Free;
inherited;
end;
procedure TCommand.SetIndex(Index: Integer);
var
IndexFrom, IndexTo: integer;
begin
if csDestroying in CommandArray.ComponentState then Exit;
IndexFrom:= Index;
inherited SetIndex(Index);
IndexTo:= Index;
if IndexFrom <> IndexTo then
CommandArray.InternalMoveItem(IndexFrom, IndexTo);
end;
function TCommand.GetDisplayName: String;
begin
result := FName;
if result = '' then result := inherited GetDisplayName;
end;
function TCommand.GetNamePath: String;
begin
if Collection <> nil then
Result := Collection.GetNamePath + FName
else
Result := inherited GetNamePath;
end;
procedure TCommand.Execute;
begin
If Assigned(FOnExecute) = True then FOnExecute(Self, Params);
end;
{ TCommands }
function TCommands.Add: TCommand;
begin
Result:= TCommand(inherited Add);
end;
constructor TCommands.Create(AOwner: TComponent);
begin
inherited Create(TCommand);
Owner:= AOwner;
end;
function TCommands.GetItem(Index: Integer): TCommand;
begin
Result:= TCommand(inherited GetItem(Index));
end;
procedure TCommands.SetItem(Index: Integer; Item: TCommand);
begin
inherited SetItem(Index, Item);
end;
function TCommands.GetOwner: TPersistent;
begin
result := Owner;
end;
{ TCommandArray }
constructor TCommandArray.Create(AOwner: TComponent);
begin
inherited Create(AOwner);
FCommands:= TCommands.Create(Self);
end;
destructor TCommandArray.Destroy;
begin
FCommands.Free;
inherited;
end;
function TCommandArray.FindCommand(CommandName: String): TCommand;
var
Loop : Integer;
begin
Result:= Nil;
For Loop:= 0 to FCommands.Count-1 do Begin
If LowerCase(FCommands.Items[Loop].CommandName) = LowerCase(CommandName) then Begin
Result:= FCommands.Items[Loop];
Break;
End;
End;
end;
function TCommandArray.FindCommand(CommandKind: Integer): TCommand;
var
Loop : Integer;
begin
Result:= Nil;
For Loop:= 0 to FCommands.Count-1 do Begin
If FCommands.Items[Loop].CommandKind = CommandKind then Begin
Result:= FCommands.Items[Loop];
Break;
End;
End;
end;
procedure TCommandArray.InternalAddItem;
begin
end;
procedure TCommandArray.InternalDeleteItem(Index: Integer);
begin
end;
procedure TCommandArray.InternalMoveItem(FromIndex, ToIndex: Integer);
begin
end;
end.
---------------------------------------------------------------------------------------------------
4. RunDll 소스
unit RunDll;
interface
uses
Windows, SysUtils, Classes, Controls, Forms, Dialogs;
type
TRunDll = class(TObject)
private
{ Private declarations }
FList : TStringList;
Function LoadDll(DllName:WideString):Integer;
public
{ Public declarations }
Constructor Create;
Destructor Destroy; override;
class Procedure Run(ModuleID, DllName:WideString; Parent:TWinControl; Visible:Boolean);
End;
implementation
uses
uSubForm;
var
FRunDLL : TRunDLL = Nil;
Constructor TRunDll.Create;
Begin
Inherited Create;
FList:= TStringList.Create(true);
End;
Destructor TRunDll.Destroy;
Begin
FList.Free;
Inherited Destroy;
End;
Function TRunDll.LoadDll(DllName:WideString):Integer;
Begin
FList.Clear;
FList.Add(DllName);
FList.Values[DllName] := DllName;
Result:= StrToIntdef(FList.Values[DllName], -1);
If Result = -1
then Begin
Result := LoadLibrary(PWideChar(DllName));
showmessage('RunDll-6-LoadLibrary =>' + IntToStr(Result));
FList.Values[DllName]:= IntToStr(Result);
End;
End;
class Procedure TRunDll.Run(ModuleID, DllName:WideString; Parent:TWinControl; Visible:Boolean);
Var
iHandle : Integer;
DllFunc : Procedure (ModuleID:WideString; App:TApplication; Parent:TWinControl; Visible:Boolean); far;
Begin
If FRunDLL = Nil then FRunDLL:= TRunDLL.Create;
Try
iHandle := FRunDLL.LoadDll(DllName);
showmessage('DllName => ' + DllName + ' | iHandle =>' + IntToStr(iHandle));
If iHandle > 32
then Begin
//windows xp
// @DllFunc:= GetProcAddress(iHandle, PChar('OpenSubModule'));
// windows 7
@DllFunc:= GetProcAddress(iHandle, PWideChar('OpenSubModule'));
If @DllFunc <> Nil
then begin
DllFunc(ModuleID, Application, Parent, Visible);
end;
End;
Except
End;
End;
end.
-----------------------------------------------------------------------------------------
5.atp2.map 의 내용중 uSubForm 관련된 부분입니다.
Line numbers for uSubForm(uSubForm.pas) segment .text
67 0001:0027EAC8 68 0001:0027EAF8 69 0001:0027EB05 72 0001:0027EB0A
76 0001:0027EB2A 82 0001:0027EB4C 85 0001:0027EB8B 86 0001:0027EB99
87 0001:0027EBA4 88 0001:0027EBB6 90 0001:0027EBCD 93 0001:0027EBD2
71 0001:0027EBD5 95 0001:0027EBDE 99 0001:0027EC14 100 0001:0027EC41
101 0001:0027EC59 111 0001:0027EC84 116 0001:0027ECD0 118 0001:0027ECD6
127 0001:0027ECE6 129 0001:0027ED41 130 0001:0027ED4F 133 0001:0027ED68
135 0001:0027ED78 136 0001:0027ED88 141 0001:0027ED98 142 0001:0027EDBC
143 0001:0027EDCF 144 0001:0027EDE2 145 0001:0027EE12 146 0001:0027EE42
147 0001:0027EE72 148 0001:0027EEA2 149 0001:0027EED2 150 0001:0027EF02
151 0001:0027EF32 152 0001:0027EF62 153 0001:0027EF92 155 0001:0027EFC2
156 0001:0027EFF2 157 0001:0027F022 158 0001:0027F052 159 0001:0027F082
160 0001:0027F0B2 161 0001:0027F0E2 163 0001:0027F100 164 0001:0027F136
165 0001:0027F16C 166 0001:0027F1A2 167 0001:0027F1D8 168 0001:0027F20E
170 0001:0027F244 175 0001:0027F24C 198 0001:0027F269 201 0001:0027F27F
205 0001:0027F600 206 0001:0027F622 208 0001:0027F636 210 0001:0027F63C
212 0001:0027F649 214 0001:0027F653 215 0001:0027F65E 221 0001:0027F684
222 0001:0027F6B1 223 0001:0027F6BF 224 0001:0027F6C5 225 0001:0027F6CD
228 0001:0027F6CF 229 0001:0027F6DD 232 0001:0027F70C 233 0001:0027F715
234 0001:0027F720 235 0001:0027F72D 238 0001:0027F734 239 0001:0027F756
240 0001:0027F76C 241 0001:0027F77F 246 0001:0027F7A4 249 0001:0027F7B0
250 0001:0027F7CC 251 0001:0027F7EA 253 0001:0027F7FE 254 0001:0027F812
248 0001:0027F815 255 0001:0027F81A 261 0001:0027F820 263 0001:0027F845
265 0001:0027F854 266 0001:0027F85E 269 0001:0027F86A 270 0001:0027F874
271 0001:0027F87E 284 0001:0027F889 289 0001:0027F8C0 290 0001:0027F8CC
291 0001:0027F8D4 294 0001:0027F8D8 295 0001:0027F8E7 296 0001:0027F8ED
302 0001:0027F8F4 303 0001:0027F909
Line numbers for uSubForm(uSubForm.pas) segment .itext
298 0002:000015F8 299 0002:00001604 301 0002:00001617
-----------------------------------------------------------------------------------------
읽어주셔서 감사합니다.
답변 꼭 부탁드리겠습니다. ^^
우선 메모리 참조에러가 발생합니다.
아래와 같이 오류난 코드만 보면 frmSub가 없으면(nil) 오류가 나겠네요.
frmMain.FindSubForm에서 찾지 못한 것 같습니다.
그렇다면 왜 찾지 못하는지를 해결하면 되겠네요.
코드 양이 많아 유니코드 문제인지는 잘 모르겠구요. 디버깅해보면 원인을 찾을 수 있을겁니다.
showmessage('4 >' + _findDllForm); ---값 잘가져옴---
fmSub := fmMain.FindSubForm(_findDllForm);
showmessage('5 >'+_findDllForm); ---값 잘가져옴---
showmessage('6 >'+_findModule); ---값 잘가져옴---
Command := fmSub.FindCommand('용영'); -- 여기서 에러가 납니다.---