2009-10-07 2 views
4

저는 Jeff Atwood's article about how errors are always the programmer's fault에 익숙하지만 실제로 델파이 .pas 파일에서 버그를 발견했다고 생각합니다.Delphi IDE에서 사용하는 .PAS 파일을 다시 컴파일 할 수 있습니까?

특히, 내가 델파이 2007 사용하고, 에러가 내 컴퓨터에서 다음 위치에있는 DBCommon.pas 파일의 라인 955에 :

C : \ 프로그램 파일 \ 코드기어 \ RAD 스튜디오 \ 5.0 \ 소스 \는 Win32 \ DB \ DBCommon.pas

그리고 코드는 이것이다 :

... 
    FieldIndex := StrToInt(Token); 
    if DataSet.FieldCount >= FieldIndex then 
    LastField := DataSet.Fields[FieldIndex-1].FieldName else 
... 

"토큰"0의 값이있는 경우, 우리는 인덱스 -1에 액세스하려고 DataSet.Field 결과가 범위를 벗어나는리스트 인덱스가됩니다.

이 오류는 사용자가 처리하기 전에 처리되기 때문에 사용자에게 제기되지는 않지만, 이러한 상황이 발생할 때마다 디버거가 중단되도록하는 것은 대단히 짜증나게합니다.

"이 예외 유형을 무시할 수 있습니다."그러나 범위를 벗어난 인덱스는 일반적으로 무시하고 싶지 않기 때문에 자주 사용됩니다.

당신과 같이 그 ORDER BY 함수가 포함 된 SELECT 문을 때 FieldIndex가 제로 원인이 상황은 다음과 같습니다

ORDER BY 
    CASE WHEN FIELD1 = FIELD3 THEN 1 ELSE 2 END 
,CASE WHEN FIELD2 = FIELD4 THEN 1 ELSE 2 END 

내가 DBCommon.pas의 버그를 수정 할 수 있지만, 델파이는하지 않습니다 재 컴파일하고 내 변경 사항이 적용되지 않습니다. .DCU 파일의 이름을 변경하면 "DBCommon.dcu"를 찾을 수 없다는 불만이 생깁니다.

내 질문에 : 내 수정 프로그램으로 DBCommon.pas를 다시 컴파일 할 수 있습니까? 그렇다면 어떻게해야합니까?

+0

당신이 버그를 재현 할 수 있습니까? 만약 당신이 품질 관리를 원한다면, 재현성있는 케이스를 메일로 보내주십시오. (거의 모든 것을 pluimers dot com이 내받은 편지함에 도착합니다)? –

+0

"제프 앳 우드의 기사에 오류가 항상 프로그래머의 잘못이 있음을 잘 알고 있습니다.하지만 델파이 .pas 파일에서 버그를 발견했습니다." <- 누가 .pas 파일을 만들었습니까? 예, 프로그래머 :) –

+1

복제 : http://stackoverflow.com/questions/1055010/how-to-recompile-a-specific-unit-from-the-vcl –

답변

12

아마도 dbcommon.pas를 프로젝트 디렉토리에 넣을 수 있습니다. 그런 다음 나머지 프로젝트와 함께 컴파일됩니다.

+0

dbcommon.pas를 기반으로하는 다른 모든 장치가 해당 디렉터리에도 복사되거나 수정되지 않은 VCL 원본이 원본 경로에 있지 않으면이 기능이 작동하지 않습니다. – mghie

+3

작동해야합니다. 유닛의 인터페이스 버전은 변경해서는 안되기 때문에, 그것을 사용하는 모든 유닛은 재 컴파일 된 버전을 받아 들여야합니다. –

+0

@ 롭 : 네가 맞다. 나는 노력했지만 실제로 작동한다. 타사 라이브러리의 구현 섹션에서 문자열을 변경하려고 할 때 문제가 발생했기 때문에 그곳의 다른 점이 무엇입니까? 인터페이스 버전을 변경하거나 변경하지 않는 것에 관한 문서가 있습니까? – mghie

2

프로젝트 소스 트리 아래에 VCL이라는 폴더가 있습니다.이 폴더에는 수정하려는 VCL 소스의 복사본을 저장합니다. 귀하의 예는 똑같은 일을하는 좋은 후보자입니다. 프로젝트의 검색 경로를 수정하여 "VCL"폴더가 Delphi 설치의 "Source"폴더보다 경로에서 빠르도록 수정해야합니다. 하나의 VCL 소스 유닛을 복사하여 수정하면 다른 VCL 소스 유닛을 종속물 일 수있는 "your"폴더로 복사해야합니다.

이유는 컴파일러가 암시하는 컴파일러 힌트와 경고가 없기 때문입니다. 힌트/경고가없는 VCL 소스의 일부가 있습니다.

1

간단히 - 예. 위의 답변 중 하나를 사용하여 [Tom 또는 Connor로]. 원본을 편집하는 대신 DBCommon.pas를 프로젝트 폴더로 복사하십시오. 이로 인해 다른 프로젝트와 컴파일은 영향을받지 않기 때문에 영향을받지 않습니다.

+1

주목할 것 같지만 응답을 표시하기 위해 스택 오버플로를 사용하는 기본 순서는 투표 수순으로 정렬하는 것입니다. 다른 답변을 말할 때 좀 더 구체적으로 기재하십시오. "위의 답변"은 실제로 어떤 답변을 말하는지 알려주지 않습니다. 각 답변 아래에있는 "링크"주소를 복사하여 직접 링크 할 수 있습니다. –

+0

죄송합니다. 물론 대답 할 때 기본적으로 같은 말을하는 사람은 2 명 밖에 없었습니다. :) 그래서 명확성을 위해 대답을 편집 할 것입니다. – Despatcher

4

수정 된 VCL 소스를 다시 컴파일 할 수있는 상황을 만드는 방법에 대한 이전 답변을 확인하십시오. 그러나 "공급 업체 지점"SCM 패턴을 사용하여 변경 관리 시스템의 변경 관리를 진지하게 고려하는 것으로 추가 할 것입니다.(참고로 SVN 사용) 간단히 말해서

:

  • 는 "벤더 소스"일본어 벤더의 카피를 작성하여 파일을 공급했다. 이것은 "깨끗한"참조 사본입니다.

  • 별도 "벤더 라이브러리"폴더에 다른 지점을 작성합니다 (VCL의 델파이 2009 버전 예 : '2009')이 깨끗 복사를 나타내는 분기

  • 만들기. 이 파일은 프로젝트에서 참조해야하는 라이브러리의 복사본입니다.

  • "공급 업체 라이브러리"분기에서 공급 업체 소스를 수정하면됩니다.

  • 공급 업체가 새 버전의 라이브러리를 제공하면 "공급 업체 소스"프로젝트에 새 버전을 체크인하고 새 버전에 대한 새 분기를 만듭니다.

그러면 벤더 수정본을 쉽게 구분할 수 있습니다. 그러나 SubVersion 및 SCM 시스템을 사용하는 경우 더욱 중요한 점은 새 공급 업체 소스를 "공급 업체 라이브러리"지사와 병합 (즉 자동)하여 공급 업체 변경 사항을 쉽게 수정할 수 있어야한다는 것입니다. 그 책에서 언급 된 "loaddirs"유틸리티가 더 이상에 의한 지원되는지 "Subversion을 사용한 버전 관리"

참고 그러나이 모든 난 그냥 우수한 오라일리 책 않았다보다 훨씬 더 나은 설명이다

저작권 문제가 있으므로 "공급 업체 할인"업데이트는 현재 수동 연습이지만 이는 드물게 발생하며 큰 부담이 아닙니다.

우리는 VCL의 경우 "공급 업체 소스"또는 "공급 업체 라이브러리"에 전체 VCL 소스 트리의 전체 복사본을 유지하지 않지만 대신이 패턴을 사용합니다. 단위. 공급 업체 지점에서 관리되는 다른 라이브러리의 경우 일반적으로 전체 복사본을 유지 관리하지만 VCL에는 필요하지 않다고 결정했습니다.

그러나이 패턴을 구현 한 것만으로도 VCL에 대해보다 포괄적 인 접근 방식을 취해야한다고 판단 할 수도 있습니다.

ymmv

+0

다른 버전의 TMS를 ​​사용하는 두 프로젝트를 어떻게 처리합니까? * 한 개발자가 업데이트하면 모든 사람이 업데이트 * 이외의 다른 해결책을 찾지 못했습니다.* 소스 코드 자체가 아니라 IDE에 설치된 구성 요소에 대해 언급하는 것은 아닙니다. * –

+1

@Lieven - 타사 라이브러리를 모든 프로젝트에서 "공통"으로 간주하므로 다루지 않아도됩니다. 예를 들어 DevExpress를 업데이트하면 그 정도면 모든 프로젝트가 업데이트됩니다. (계속) – Deltics

+1

@Lieven, cont. 우리는 서로 다른 IDE 레벨 (BDS2006 및 RS2010)의 프로젝트를 가지고 있습니다. 이것이 필요할 때 우리는 벤더 브랜치를 각 프로젝트 폴더 구조 아래에 별도로 배치하여 2006 년 최종 벤더 지점이 2010 년 (및 "현재") 벤더 지점과 분리되도록했습니다. 그러나 우리는 IDE가 아닌 표준 설치 프로그램에서 IDE 구성 요소를 설치합니다. 런타임 패키지를 사용하지 않기 때문에 가능합니다. IDE 구성 요소의 게시 된 등록 정보가 공급 업체 분기의 등록 정보와 일치하면 모든 것이 정상입니다. – Deltics

4

하지만 할 필요는 없습니다. VCL 유닛을 재 컴파일한다는 것은 때때로 유닛의 인터페이스를 변경했거나 컴파일러가 혼란스러워서 이 인터페이스를 변경했다고이 생각하기 때문에 나머지 VCL 유닛을 다시 컴파일하는 것을 의미합니다. 또한 VCL 유닛을 다시 컴파일하면 Delphi의 런타임 패키지를 다시 컴파일 할 수 없기 때문에 대부분의 런타임 패키지를 사용할 가능성이 배제됩니다.

다시 컴파일하는 대신 런타임 패치를 사용할 수 있습니다. TNT Unicode controls에있는 메서드를 사용했지만 Madshi은 함수를 사용자 구현과 바꾸는 방법을 제공합니다. OverwriteProcedure 루틴을 찾습니다 TNT 유니 코드 라이브러리와

var 
    Old_GetIndexForOrderBy: Pointer; 

HookCode(@DBCommon.GetIndexForOrderBy, 
     @Fixed_GetIndexForOrderBy, 
     Old_GetIndexForOrderBy, 
     0); 

: 당신이 당신의 자신의 장치에 DBCommon.GetIndexForOrderBy의 구현을 복사하여 수정을 할 경우, 당신은 당신의 자신과 VCL 버전을 패치하려면이 명령을 사용할 수 있습니다 TntSystem 장치.public이 아니므로 유닛 인터페이스에서 선언하거나 자신의 유닛으로 복사해야합니다. 그럼 당신은 위의 Madshi 코드처럼 많이를 호출 할 수

var 
    Old_GetIndexForOrderBy_Data: TOverwrittenData; 

OverwriteProcedure(@DBCommon.GetIndexForOrderBy, 
        @Fixed_GetIndexForOrderBy, 
        @Old_GetIndexForOrderBy_Data); 
2

"나는 오류가 항상 프로그래머의 잘못입니다 방법에 대한 제프 앳 우드의 기사에 대해 잘 알고,하지만 내가 진실로이 델파이에서 버그를 발견 믿는다 .pas 파일 "

나를 농담하나요? 델파이를 사용하면 항상 볼랜드를 먼저 비난합니다. 뭔가 이상한 점이 있습니다. Google로 이동하여 델파이 버그인지 확인하십시오. 사이트에 유사한 보고서가 없으면 코드를 한 줄씩 확인하십시오.

델파이를 다시 설치 한 후 원래 PAS 파일을 6 (6) 곳에 패치해야합니다. 새로운 델파이 설치에 나타나는 수많은 버그가 있으며 쉽게 재현 할 수 있습니다. Delphi (우리 모두가 좋아하는 것)는 버그로 가득 차 있습니다. 이 주변에는 전체 역사가 있습니다. 외부 패치를 배포하는 사람이 너무 많습니다 (예 : http://andy.jgknet.de/blog/?page_id=288). Borland/Imprise/GoGear/Embarcadero는 계속 무시합니다. FastMM을 공개 할 때 그들이 포함 된 것은 놀라운 사실입니다.

어쨌든 이러한 PAS 파일을 다시 컴파일 했으므로 원래 DCU를 패치 된 파일로 바꿉니다.

1

당신은 설정할 수 있습니다 DataSetProvider.Option.poRetainServerOrder = True

관련 문제