Post List

2015년 1월 6일 화요일

[Reny Kim] DLL 제작방법 – 6.Troubleshooting

VC에서 제작한 DLL을 다른 언어에서 사용하게 되는 경우 흔히 접하게 되는 문제가 있다. 이는 대부분 Naming Convention 또는 Calling Convention의 차이에서 발생하게 되는데 각 유형별 문제점에 대한 해결방안을 설명한다.

· Entry Point Error
VC에서 제작한 DLL을 다른언어에서 사용하는 경우 흔히 발생하는 문제이다. DLL 함수를 다른언어에서 호출하는 경우 아래와 같이 입력점을 찾을 수 없다는 에러가 발생하는 경우가 있다.


이는 DLL 내에서 호출한 함수를 찾지 못한 경우인데, 이는 대부분 Naming Convention에 의한 오류이다. 1.1.2 장에서 설명했듯이, VC는 기본적으로 C++의 Naming Convention을 사용하므로 Export되는 함수명은 실제 작성한 함수와 다르게 Export된다. 따라서 아래와 같이 extern “C” 키워드를 사용해서 Naming Convention을 조정하여야 VB에서 인식가능하다. 이는 확장자가 “cpp”인 경우 반드시 extern “C” 를 사용하여야 하며, 확장자가 “.c”인 경우는 필요하지 않다.
?
extern “C” {
?
DLLFunction void somefunc();
?
}

· Calling Convention Error
DLL 함수를 호출한 경우, 함수가 실행은 됐으나, Return 시 아래와 같이 DLL 호출규정이 잘못되었다는 에러가 발생하고 다운되는 경우가 있다.

?
이는 VC와 다른언어의 Calling Convention의 차이로 인하여 발생하는 에러이다. 1.1.2 장에서 설명한 바와 같이 VC는 기본적으로 “__cdecl” 방식을, 다른 언어는 “__stdcall” 방식을 기본으로 사용한다. 따라서 Calling Convention을 “__stdcall” 방식으로 조정하여야 다른언어에서 정상적으로 사용할 수 있다. 이는 VC의 Project 속성에서 조정하거나, 함수에 명시적으로 __stdcall을 선언한다.
?
또한 “__stdcall” 방식인 경우 Module Definition File(.def)을 추가로 작성해야 한다. 아래와 같이 def 파일을 프로젝트에 추가하고 export할 각 함수를 명시한다.
DllTest2.def
LIBRARY?????????????????? “DllTest2.DLL”
DESCRIPTION?????????? ‘SIMPLEDLL Windows Dynamic Link Library’
?
EXPORTS
somefunc1? @1
somefunc2? @2
위와 같은 과정을 거친 후, DLL을 작성하면 위의 문제가 해결됨을 알 수 있다.

· ESP Error
자주 발생하는 에러는 아니지만 간혹 만나게 되는 문제이다. DLL 함수를 호출할 경우, 아래와 같은 에러를 발생하고 다운되는 경우가 있다.


에러는 “The value of ESP was not properly saved across a function call. This is usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention” 라고 표시된다. 이는 DLL의 함수에서 다른 DLL에 포함된 함수를 호출하는 구조로 함수를 작성한 경우, 가끔 발생하게된다. 이 에러는 DLL간의 Calling Convention의 차이로 인하여 발생하는 듯 한데, 이는 DLL에서 호출되는 다른 DLL의 함수를 모두 1.3.2 장에서 설명한 Explicit Link로 처리하면 더 이상 발생하지 않는다.

댓글 없음:

댓글 쓰기