2012-05-09 7 views
4

모 놀리 식 응용 프로그램을 모듈화하는 데 도움이되도록 디버그 빌드에서 사용할 패키지를 설정하는 중이고 릴리스 빌드에 대해 하나의 EXE 파일로 컴파일하는 중입니다. .런타임 패키지로 빌드하는 동안 "가져온 데이터 참조가 필요합니다"를 해결하는 방법

우리 패키지 중 하나 (EAUtils)에는 현재 [DCC Error] E2201 Need imported data reference ($G) to access 'SMsgDlgWarning' from unit 'SystemUtils'을 생산하는 장치가 포함되어 있습니다.

EAUtils 패키지 자체를 빌드 할 때 발생합니다. 아직 EAUtils에 의존하는 패키지를 만드는 것이 아닙니다. EAUtils는 rtl/vcl 패키지 및 Jedi WinApi 장치 용으로 만든 패키지에만 의존합니다.

// This is a TaskDialog override, with the same args as the old MessageDlg. 
function TaskDialog(const aContent: string; const Icon: HICON = 0; 
    const Buttons: TTaskDialogCommonButtonFlags = TDCBF_OK_BUTTON): Integer; 
const 
    Captions: array[TMsgDlgType] of Pointer = (@SMsgDlgWarning, @SMsgDlgError, @SMsgDlgInformation, @SMsgDlgConfirm, nil); 
var 
    aMsgDlgType: TMsgDlgType; 
    aTitle: string; 
begin 
    aMsgDlgType := TaskDialogIconToMsgDlgType(Icon); 
    if aMsgDlgType <> mtCustom then 
    aTitle := LoadResString(Captions[aMsgDlgType]) 
    else 
    aTitle := Application.Title; 

은 구체적으로 이러한 모든 Vcl.Const에서 선언 SMsgDlgWarning, SMsgDlgError, SMsgDlgInformationSMsgDlgConfirm을 참조 한 결과이다

는 라인의 결과이다.

이 코드는 단일 실행 파일을 작성할 때 오류없이 컴파일됩니다.

최적화 방법으로, 우리의 포함 파일에는 {$IMPORTEDDATA OFF}이 포함되어있어 전역 변수와 상수에 더 빨리 액세스 할 수 있습니다. http://hallvards.blogspot.com/2006/09/hack13-access-globals-faster.html을 참조하십시오.

오류 (http://docs.embarcadero.com/products/rad_studio/delphiAndcpp2009/HelpUpdate2/EN/html/devcommon/cm_package_varref_xml.html)의 설명서에 따르면 이것이 원인이며 "문제를 완화하려면 일반적으로 $ IMPORTEDDATA 스위치를 켜고 오류를 생성하는 장치를 다시 컴파일하는 것이 가장 쉽습니다."

그래서 프로젝트 파일의 Delphi Compiler | Compiling | Debugging 섹션에 Use imported data references을 true로 설정하여 {$IMPORTEDDATA ON}을 포함 파일에 설정하고 이중 설정을 확실하게했습니다.

문서와 달리 불행히도 문제가 완화되지 않았습니다. 문제가되는 코드 바로 위의이 컴파일러 지시문을 설정하고 패키지를 다시 작성해도 오류가 제거되지 않았습니다.

이 E2201 오류를 해결하려면 무엇이 필요합니까? 확실치 않지만 SMsgDlgWarning과 그 친구가 리소스 문자열이라는 것이 중요 할 수 있습니까?

+1

패키지를 컴파일 할 때이 오류가 발생하지만 건물이 항상 작동합니다. – jpfollenius

+0

@Smasher : 고마워.하지만 내가 지었다.조건부 정의와 너무 많은 번거 로움을 겪고 Shock-F9가 내 마음에 들었습니다 :-) –

+0

'$ IMPORTEDDATA'가있는 유닛을 포함하고있는 원본 패키지를 다시 빌드하면 오류가 발생하지 않아야합니다. 종속 패키지를 빌드 할 때 결과 .dcu 및 .dcp를 사용하고 있는지 확인하십시오. –

답변

8

오류 메시지는 IMHO입니다. 오해의 소지가 있습니다. Vcl.Consts$G-으로 컴파일되어 문제의 원인입니다. (이 현지화를 나누기하지만)도 문자열의 const를 배열 컴파일 사용

function Captions(AType: TMsgDlgType): Pointer; 
begin 
    Result := nil; 

    case AType of 
    TMsgDlgType.mtWarning: 
     Result := @SMsgDlgWarning; 
    TMsgDlgType.mtError: 
     Result := @SMsgDlgError; 
    TMsgDlgType.mtInformation: 
     Result := @SMsgDlgInformation; 
    TMsgDlgType.mtConfirmation: 
     Result := @SMsgDlgConfirm; 
    end; 
end; 

:

const 
    Captions: array[TMsgDlgType] of string = (SMsgDlgWarning, SMsgDlgError, SMsgDlgInformation, SMsgDlgConfirm, ''); 

하거나 포함하는 자신 만의 패키지를 만들 수 해결 방법으로, 다음과 같이 사용할 수 있습니다 Vcl. * 단위를 {$G+}으로 변경하고 표준 vcl 패키지 대신이를 사용하십시오. 나는 첫 번째 해결책을 선호한다. 후자는 잠재적으로 나중에 배포 (소위 "DLL 지옥")와 함께 더 많은 문제를 만들 수 있습니다.

+0

감사합니다! 로컬 var 및 일부 캐스팅을 시도했지만 함수를 사용하지는 않았습니다. –

+0

환영합니다, 감사합니다! 또한 작동하는'const array of string'의 경우도 추가했습니다. –

+0

다른 곳에서 편리하게 사용할 수 있으므로 흥미롭고 좋아요. 원본 resourcestrings의 현지화와 관련하여 어떤 효과가 있을지 궁금합니다. 내 생각 엔 const 배열은 컴파일 타임에 resourcestrings의 값으로 초기화 될 것이고 아이템은 현재 정상적인 문자열이되고 리소스 dll에서 번역 된 문자열로 대체되지 않으며 LoadResString에 전달 될 수 없습니다 원래의 자원 확보 기록의 주소로 작업하고 있습니다. –