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

C++빌더 Q&A
C++Builder Programming Q&A
[60431] Re:Re:SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요.
이영섭 [] 3855 읽음    2010-03-11 21:07
자세한 답변 감사드립니다. AnsiString이 클래스라는 사실을 종종 망각하곤하네요...

그 뒤에 실험해봤는데 노트북에서는 XP나 윈도우7 모두 성공이었고, 데스크탑은 모두 실패인걸로 봐서 CPU에 영향을 받는것도 있나봐요.
아무튼 좋은 강의 감사드립니다. 덕분에 메모리 주소 보는 법도 배웠습니다. 
이 은혜를 어찌 갚아야할지 모르겠네요. 

언제나 좋은 답글을 달아주시는 장성호님에게 좋은 일만 가득하길 기원합니다.

장성호 님이 쓰신 글 :
: 음..
: 핵심 키워드
: AnsiString 은 RefCount가 0 이면 자동으로 free됩니다.
:
:
: 코딩 실수한 부분
: 다음 코드가 실수하신 코드인데요
:
: ExVal.lpDirectory = AnsiString(ExtractFilePath(Application->ExeName)).c_str();
: 

:
: 원인은?
:
: AnsiString은 같은 내용을 여러군데 대입하더라도 내용이 완전히 복사되지 않고
: 내부적으로 포인터(address)가 copy되고 RefCount가 증가합니다.
:
:  AnsiString이 free 될때는 내용을 완전히 삭제하는것이 아니라 RefCount를  하나 감소시킵니다.
:
:  이때 만약 RefCount가 0(제로)가 되면 완전히 힙에 잡혀있는 내용이 free되구요
:  위 코드에서 AnsiStirng을 사용하셨지만
:  ExtractFilePath 의 결과를 받는 AnsiString 이 없습니다.
:
:  즉  AnsiStirng.c_str(); 함수가 호출된뒤에
:  ExtractFilePath의 결과인 AnsiString은 RefCount가 0 이기 때문에 자동 free됩니다.
:
:  그런후에 lpDirectory 에 담긴 address만 가지고  그 위치에 접근하면
:  accessviolation이 나거나 쓰레기 값이 그 위치에 들어있겠죠
:
:  님 pc에서 에러가 발생하지 않는것은 행운입니다.

: dis-assembler 화면
:
:
:
:
: SHELLEXECUTEINFO  구조체의 lpDirectory  변수는 address만 가지고 있지
: 문자열 전체를 가지고 있지 않습니다.
:
: 그런데 위 그림에서 본것처럼
:  ExVal.lpDirectory = AnsiString(ExtractFilePath(Application->ExeName)).c_str();
: 위 문장에서 address.만 copy하고 실제 문자열이 담긴 AnsiString은  free되어버렸습니다.
:
: 그런다음에 ShellExecuteEx 를 호출하기 때문에 문제가 발생하는것 입니다.
:
: 해결방법
: 1. ExtractFilePath의 결과를 다른 AnsiString 에 담아두고..
: 2. 담아둔 AnsiString.c_str()을 lpDirectory 에 설정합니다.
: 3. 그런후에  ShellExecuteEx 를 호출하구요
:
:
: 주의사항
: ExtractFilePath의 결과를 다른 AnsiString은 반드시  ShellExecuteEx  가 호출된후에 소멸되어야 합니다.
: (블럭안에서 AnsiString을 선언하면 함수종료전에 AnsiString이 소멸될수가 있습니다.)
:
: 그럼..
:
:
:
: 이영섭 님이 쓰신 글 :
: : void __fastcall TfrmVersion::OpenFile()
: : {
: :
: :         SHELLEXECUTEINFO ExVal;
: :     ExVal.cbSize = sizeof(SHELLEXECUTEINFO);
: :     ExVal.fMask = NULL;
: :     ExVal.hwnd = NULL;
: :     ExVal.lpVerb = NULL;
: :     ExVal.lpFile = "TEST.exe";
: :     ExVal.lpDirectory = AnsiString(ExtractFilePath(Application->ExeName)).c_str();
: :     ExVal.nShow = SW_SHOWNORMAL;
: :     ExVal.hInstApp = NULL;
: :
: :         Application->ProcessMessages();
: :         if(!ShellExecuteEx(&ExVal))
: :                 ShowMessage("실패"); 
: :          Close();
: : }
: :
: :
: : 이렇게 놓고 실행을 시켰는데, 제 컴퓨터에서는 잘 작동하는데 다른 컴퓨터에 옮기니까 되는게 있고 안되는데가 있습니다. 도대체 원인을 모르겠네요.
: :
: :  제 컴퓨터에서 되길레 옆 컴퓨터에 배포했는데, 똑같이 xp라 아무 문제 없을줄알았는데 그게 아니더라구요.
: :  제쪽에서는 이상없이 test.exe파일을 실행하는데,  딴 컴퓨터에서는 test.exe파일을 못찾는다고 나오더라구요.
: :
: :
: :  혹시 이런 증상을 보신적이 있나요?

+ -

관련 글 리스트
60425 SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요. 이영섭 2814 2010/03/11
60426     Re:SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요. 장성호 3013 2010/03/11
60431         Re:Re:SHELLEXECUTEINFO를 사용해서 다른 exe 파일을 사용할 경우 이상하게 작동해요. 이영섭 3855 2010/03/11
Google
Copyright © 1999-2015, borlandforum.com. All right reserved.