|
즐겨찾기
카테고리
전체
잡담 기술정보 컬럼 좋은 글귀 영어학습 Rahul과의 편지 아이디어 이력 사항 독백 마이라이프 실험실 디버깅 번역 노트 작업목록 MVP Book ImageBinary 세션 유지 영어면접 우리는 지금... 미분류 최근 등록된 덧글
링크 깨졌음
by das at 02/02 작업하면서 나름 얻은 .. by 홍번구 at 12/05 퍼갑니다. 마지막 by sm.. by 홍번구 at 12/05 order cialis online .. by order cial at 07/22 doxycycline online .. by doxycyclin at 07/21 accutane online <.. by accutane at 07/21 viagra online online .. by viagra onl at 07/21 cheap cialis online .. by cheap cial at 07/20 cheap cialis online .. by cheap cial at 07/19 order viagra online .. by order viag at 07/19 라이프로그
이전블로그
이글루링크
이글루 파인더
|
처음 이 주제를 다루게 되었을 때, 두가지 상황을 생각했다.
1. 네이티브 확장 DLL의 소스를 변환하여 managed DLL을 생성한다. 2. 확장 DLL을 감싸는 Wrapper 클래스를 작성한다. 이 두가지 방법 중에서 첫번째 방법이 더 깔끔하고 확실하다고 생각했기 때문에, 당연히 첫번째 방법부터 시도했다. 물론 첫번째 방법이 가능한 이유는 내가 소스 코드를 가지고 있었기 때문에 가능한 일이었다. 일단 전체 소스를 받아서 컴파일해 보았는데, 이 소스에도 문제가 있는지 컴파일이 제대로 되지 않았으며 이 문제는 나중에 해결한다고 하더라도 __gc 클래스를 외부에 익스포트하는 과정에서 __gc 클래스는 unmanaged 클래스를 멤버 변수로 가질 수 없다는(대신 포인터는 가능하다)걸 발견하여 전체 소스를 모두 수정해야 했으며, 특히 이 소스는 const를 과도하게 사용하여 내가 이를 수정하기가 만만치 않았다. 두번째 방법은 내가 그동안 외부에서 공개된 DLL을 사용할 때 많이 사용했던 방법이어서 첫번째 방법이 되지 않을 경우, 곧바로 테스트해보고 싶은 방법이었다. 이 방법을 시작하기전에 다음과 같은 사항들을 확인하였다. - managed C++ 클래스 라이브러리를 C#에서 손쉽게 사용할 수 있는가? 데이터 변환은 용이한가? - 네이티브 C++ 클래스 라이브러리를 managed C++로 만들 수 있는가? Wrapper 클래스의 작성이 비교적 용이한가? 이 방법을 간단히 테스트해 본 후, 두번째 방법에 확신을 갖게 되어 곧바로 작업에 들어갔다. 프로그램을 진행하는 성격상 여러 가지 예제 프로그램을 작성해 보면서 예제에서 작성한 소스를 토대로 전체 프로그램을 완성해가기 때문에 앞서 만든 예제를 토대로 managed C++ 클래스 라이브러리를 작성하기 시작하였다. ------------------------ 참고 사항 네이티브 C++ 클래스 라이브러리에서 익스포트하는 헤더 파일을 managed C++ 클래스 라이브러리에서 include 했더니 다음과 같은 에러가 발생하였다. 이상한 점은 이 에러가 managed C++ 응용 프로그램에서는 절대로 발생하지 않는다는 것이었다. 일단 링크 에러였기 때문에 링커 옵션에서 msvcrt.lib libcmtd.lib를 추가하고 컴파일 해 보았지만, 이번에는 main 함수가 없다는 오류를 출력하였다. 사실 DLL에서 main 함수가 필요하지는 않지만 컴파일 오류를 없애기 위해서 CPP 파일에 더미 main 함수를 추가하였더니 컴파일이 아무 문제없이 정상적으로 수행되었다. LINK : error LNK2020: 확인되지 않은 토큰(0A000038) delete LINK : error LNK2020: 확인되지 않은 토큰(0A000059) _CxxThrowException LINK : fatal error LNK1120: 2개의 확인할 수 없는 외부 참조입니다. ------------------------ 내가 필요한 정보는 네이티브 C++ 클래스의 헤더 파일과 컴파일된 DLL 파일 뿐이었다. managed C++ 클래스 라이브러리 프로젝트를 생성하고 동시에 이를 테스트할 수 있는 콘솔용 C# 프로젝트를 생성하였다. 클래스 라이브러리 쪽에서 테스트용 클래스를 만들어 본 후, 앞으로 작업을 진행해 나가야하는 시나리오를 가늠해보기 위해서 C# 프로젝트에서 해당 DLL을 테스트해보았다. 테스트가 제대로 진행되는 것을 확인한 후, 헤더 파일에 있는 모든 C++ 클래스에 대한 Wrapper 클래스를 하나씩 작성하기 시작했다. 방법은 헤더 파일에 있는 클래스 선언부분을 복사하고 나서 private 부분은 모두 삭제하고 내부용으로 사용되고 있는 함수들도 모두 삭제하였다. public으로 공개된 함수만을 간추린 후, 데이터 타입이 C#에서도 사용할 수 있도록 바꾸어 주었다. 이 과정에서 const는 무조건 삭제하였으며 char *는 String *로 바꾸어 주었다. 가장 문제가 되었던 점은 네이티브 DLL에서 char *를 받을 때, 내가 작성하고 있던 managed DLL에서는 String*를 받아야 했기 때문에 이 둘의 데이터 변환이 필요하였다. System::String 클래스에는 char *를 반환해주는 함수가 없었다. 그래서 인터넷을 검색하여 MS 사이트로부터 다음과 같은 기사를 찾을 수 있었다. 이 링크에서는 3가지 방법을 추천하고 있었는데, 나는 두번째 방법을 사용하였다. 기본적인 문제들이 해결되니 나머지는 상당히 반복적인 작업 뿐이었다. 마지막으로 namespace CCZZANG과 namespace COM이라는 더미(dummy) 네임스페이스를 사용하는 것도 잊지 않았다. 느낀점 사실 프로젝트를 진행하기 전에는, 앞서 소개했던 두 가지 방법 중에서 첫번째 방법이 해결책이라고 생각했었기 때문에 일이 제대로 진척되지 못했다. 다행히도 두번째 방법도 함께 고려를 하고 있어서 이 둘을 병행하여 테스트해본 것이 주요했다. 아울러 한 두번만으로 포기하지 않고 일을 끝까지 진행했던 것이 프로젝트를 완성하게된 힘이 아닌가 싶다. 아마도 나와 같은 문제로 많은 C++ 개발자들이 어려움을 겪고 있을거라고 생각한다. 왜냐하면 네이티브 Win32 환경에서 .NET 환경으로 넘어가는 일이 쉬운일은 아니기 때문이다. 또한 데이터 호환에서도 문제가 많고 이 프로젝트를 진행하는 개발자는 네이티브와 .NET 환경을 모두 제대로 이해하고 있어야 하기 때문이다.
|