1 개요 #
SDL이나 대규모 라이브러리같은 경우 간단히 쓰고는 싶은데 매번 빌드하려면 고생일 수 밖에 없습니다. 게다가 SDL처럼 LGPL같은게 걸려있으면 DLL 배포가 기본일 경우가 있죠. (이것은 정적 링크를 하기가 버거롭다는 얘기...) 이럴때 괜히 msys에서 빌드하면서 시간죽이는 거보다 간단히 .lib -> .a 로 변환하면 쉽게 해결되는 경우가 많습니다. (오호~
) 그래도 위 mingw faq의 내용그대로 하면 삽질이 다소 필요해 제나름대로 정리해보았습니다.
) 그래도 위 mingw faq의 내용그대로 하면 삽질이 다소 필요해 제나름대로 정리해보았습니다.
2 그래도 msys가 필요하다! #
흐음... 우선 변환작업을 위해서는 다음과 같은 3가지 툴이 필요합니다.
- pexports
- reimp
- dlltool
- sed
pexports는 DLL의 심볼들을 표준출력으로 주욱 나열해주는 프로그램입니다. 이것은 http://www.mingw.org의 다운로드에 가보시면
mingw utilities라고 하는 게 있습니다. 다운받아서 mingw 디렉토리에 설치합니다. mingw 표준 디렉토리에 맞게 압축되어있으므로 cygwin에 푸는 것은 좋지 않은 방법이라고 생각합니다. 다 풀었으면 이제 pexports와 reimp를 사용할 수 있습니다!
mingw utilities라고 하는 게 있습니다. 다운받아서 mingw 디렉토리에 설치합니다. mingw 표준 디렉토리에 맞게 압축되어있으므로 cygwin에 푸는 것은 좋지 않은 방법이라고 생각합니다. 다 풀었으면 이제 pexports와 reimp를 사용할 수 있습니다!
3 _cdecl일까? _stdcall일까? #
위 참고 링크와 기타 글을 읽어보면 win32 DLL의 함수호출방식은 _cdecl과 _stdcall 두방식 중 하나를 택하고 있습니다. 그럼 현재 변환하고자 하는 DLL이 둘중 어느방식인지를 알아봐야겠죠. _cdecl로 컴파일되어있는 SDL을 예를 들어보겠습니다. 다음과 같이 실행해보면,
pexports sdl.DLL함수들 이름이 주욱 나오는데 모두 앞에 _문자가 안붙고 정상적으로 나오는 것을 볼 수 있습니다. 이런 경우가 대부분인데 이때는 _cdecl이므로 가장 쉽게 변환할 수 있는 경우라고 생각하시면 됩니다. 하지만, 몇몇 오픈 소스 라이브러리나 특히 C++로 작성된 라이브러리들은 간혹 _stdcall을 사용할 때가 있는데 위 명령을 실행해보면 함수 이름 앞에 _문자가 붙어나오는 경우입니다. 이럴때에는 _stdcall이라 생각하시면 됩니다.
4 _cdecl 방식 변환 방법 #
이때에도 두가지 방법이 있습니다. .lib가 존재할 경우와 DLL화일만 가지고 있는 경우입니다. .lib가 붙어있는 "완벽한" SDK의 경우라면 다음과 같이 실행하면 됩니다.
reimp sdl.lib위와 같이 실행하면 libsdl.a라는 화일이 생깁니다. lib 접두어와 .a 확장자는 자동으로 붙으므로 나름대로 이름을 바꿔주면 됩니다. 이제 맘대로 링크해서 쓰면 됩니다.
헌데, DLL만 배포하는 경우도 많습니다. (오래된 프로젝트일경우가 대부분이죠.
) 이럴 경우 다음과 같은 방법을 취합니다. 만일 존재하는 DLL이 foo.dll이라고 가정하고 결과 라이브러리 화일을 libfoo.a로 뽑아낸다고 가정하겠습니다.
) 이럴 경우 다음과 같은 방법을 취합니다. 만일 존재하는 DLL이 foo.dll이라고 가정하고 결과 라이브러리 화일을 libfoo.a로 뽑아낸다고 가정하겠습니다.
pexports foo.dll | sed "s/^_//" > foo.def dlltool -d foo.def -l libfoo.a
이제 링크해서 사용해봅니다.
정말 간단하다는 것을 알수 있습니다. (mingw 개발팀에 찬사를~)
정말 간단하다는 것을 알수 있습니다. (mingw 개발팀에 찬사를~)
5 _stdcall 방식 변환 방법 #
이 경우는 DLL로부터 밖에 추출할 수 밖에 없습니다. stdfoo.dll을 예로 들어보겠습니다.
pexports stdfoo.dll | sed "s/^_//" > stdfoo.def dlltool -U -d stdfoo.def -l libstdfoo.a엇, -U 밖에는 차이가 없죠? 그렇습니다. 위 명령을 요약하면 우선 DLL로부터 심볼을 _문자를 모두 걷어내고 뽑아낸다음, _문자를 앞에 붙여주면서 만들어준다는 뜻입니다. 끝났습니다. 링크해봅니다.








