2010년 8월 16일 월요일

[C++/CLI] BadImageException

BadImageException













 C++/CLI 로 만든 dll을 .NET 응용프로그램에 참조 시킨 후, 해당 dll에 접근 하니까 아래와 같은 예외가 발생한다.










C++/CLI 사용에 있어 예외가 발생하면 항상 긴장하게 된다..








위와 같은 문제가 발생할 수 있는 경우는 여러가지가 있다.






나의 문제는 C++/CLI 프로젝트 플랫폼이 x64로 설정되어 있는데 x86 환경에서 해당 모듈을 사용하려 하니까 발생하는 문제였다.













간단한 문제였지만 기록차 작성한다.

[C++/CLI] warning LNK4199: /DELAYLOAD:OleAcc.dll을(를) 무시합니다.OleAcc.dll에서 가져오기를 찾을 수 없습니다.



warning LNK4199: 


/DELAYLOAD:OleAcc.dll을(를) 무시합니다. 


OleAcc.dll에서 가져오기를 찾을 수 없습니다.














 해당 경고 메시지가 C++/CLI 사용중에만 발생하는지, 아니면 MFC 프로젝트에서도 발생하는지는 모르겠다. MFC 를 사용하면서 저런 경고 메시지를 본적은 없었는데.. 그래서 일단 카테고리는 C++/CLI로 한다.





 C++/CLI 프로젝트를 빌드하니 1개의 경고 메시지가 나왔다. 경고는 무조건 해결할것!!













메시지를 보면 "/DELAYLOAD" 단어가 보인다. 지연 로드 옵션이다. 프로젝트 옵션에서 지연 로드 옵션 설정하는 부분을 가보자. 





프로젝트 속성 → 구성 속성 → 링커 → 입력 → 지연 로드된 DLL















상속된 값에 OleAcc.dll 이 보이고 하단에 "부모 또는 프로젝트 기본값에서 상속" 체크되어 있다. 이 체크를 해제하면 된다.













체크 해제하면 지연 로드된 DLL 항목에 "$(NOINHERIT)" 값이 쓰인다.








경고 메시지는 해결하였는데, 발생한 원인과 설정 변경으로 이한 차이점은 더 알아봐야 할 것 같다.

2010년 8월 14일 토요일

Suppressing C# Compiler Warnings













Suppressing C# Compiler Warnings
















 소스 코드를 컴파일 하면 VS의 오류창이나 출력창에 경고나 에러 목록을 보여준다. 나는 프로젝트의 경고 레벨을 최고로 높이고, 소스 코드 정적 분석을 수행하여 어떠한 오류도 출력 되지 않아야 한다고 배웠다. 지금은 누구하나 강요하는 사람은 없지만 스스로 지키려고 노력한다. 경고가 나오면 경고 메시지가 나오지 않게 수정하는것을 원칙으로 하고!! MFC 에서와 마찬가지로 C# 에서도 경고 메시지를 무시하는 방법이 있어 알아보고 넘어가려 한다.








■ 테스트를 위한 경고를 발생하는 코드 작성









internal class TestClass


{


        private int unused;


        private int assigned = 3;


}





위 코드를 컴파일 하면 출력창에 다음과 같은 경고 메시지가 출력된다.








warning CS0169: The field 'WindowsFormsApplication1.TestClass.unused' is never used


warning CS0414: The field 'WindowsFormsApplication1.TestClass.assigned' is assigned but its value is never used






첫 번째 경고는 변수가 선언만 되었지 사용되지 않았음을 말하고, 두 번째 경고는 변수가 할당 되었지만 사용되지 않았음을 말한다. 








■ 특정 경고 무시하기





#pragma warning disable 경고번호








internal class TestClass


{


#pragma warning disable 169, 414


        private int unused;


        private int assigned = 3;


}






#pragma warning disable 을 사용하여 169번, 414번 경고를 무시하게 했다. 이렇게 하면 이 이후의 모든 코드에서 169번, 414번 경고는 무시되게 된다.








■ 경고 무시 해제





#pragma warning restore 경고번호









internal class TestClass


{


#pragma warning disable 169, 414


        private int unused;


        private int assigned = 3;


#pragma warning restore 169, 414


}
















그래도 경고는 무시할게 아니라 꼭!! 수정하자.















2010년 8월 12일 목요일

오류 : EventType clr20r3 and Solution

오류 : EventType clr20r3 and Solution









 .NET 응용프로그램 배포를 위한 작업을 하다 직면한 문제이다. 분명 프로젝트를 컴파일하고 실행 시켰을때는 아무 문제가 없었는데 배포 후 실행하면 다음과 같은 오류 메시지가 실행 되었다.




<그림 1>




<그림 2>




이런 망할... 왜 오류가 발생했는지 직접적으로 말해 달란 말이다!!! ㅠㅠ



자료를 찾아본 결과 .NET Framework 2.0 에서 처리되지 않은 예외가 발생했을 때 기본 정책으로 응용프로그램을 종료시켜 버리기 때문이라고 한다. .NET Framewor 1.0/1.1 에서는 처리되지 않은 예외가 발생하면 무시한다. 



 그럼 어떤 모듈에서 어떤 메소드, 어떤 예외가 처리되지 않은 것일까?? <그림 2>를 보면 확인할 수 있다. P4 항목이 모듈 이름이며, P2가 메소드 번호, P8은 오프셋, P9는 처리되지 않은 예외 이름이다. 이 정보를 토대로 해결하려 했으나.. 생각보다 간단하지 않았다..



다음 링크를 참조







<그림 2>를 자세히 보다 보니.. P9 즉, 처리되지 않은 예외 정보가 System.Componentmodel.License 였다. 이 예외는 몰까..

결국 알고보니 배포했던 응용프로그램이 외부 Component 를 사용함으로써 발생한 예외문제였다. 

Component 배포 시 *.OCX 파일을 함께 배포하며 자동 등록하게 설정한다. 일반적인 경우인지는 모르겠으나 내가 사용한 *.OCX 파일들의 Component들은  *.lic 파일이 있어야 런타임에 정상적으로 실행되었다. Component 들이 런타임에 *.lic 파일을 참조하고, 만약 없다면 Component 내부에서 예외를 발생시키는 것 같다.



또 배포에 있어 이 상황 말고 다른 상황을 맞이한다면 참조한 링크들 처럼 분석해야 될지도 모르지만.. 위와 같은 경우에서도 발생한다는 것을 알아뒀으면 한다. 이게 경험이지 모.





■ 참조





2010년 8월 4일 수요일

C# 4.0 / VS 2010 Review

C# 4.0 / VS 2010 Review












 C# 개발팀에서 만든 PowerPoint 자료. 

MSDN... 이용할 줄 알면 참 좋군.