아래는 dll 호환을 알아보며 호출 규약에 대해 정리해본 내용인데
결국 __cdecl 로 만들어진 dll 은 VB 에서 사용할 수 없다 는 결론이 나왔는데요
다른 방법이 있거나 틀린 부분은 알려주시면 감사하겠습니다
1. 매개 변수 읽는 순서 __stdcall 오른쪽->왼쪽 __cdecl 오른쪽->왼쪽
2. 스택 정리 __stdcall 는 불려진 쪽에서 한다 __cdecl 는 호출한 쪽에서 한다
3. extern "C" 일 때의 네임맹글링 __stdcall 는 _foo@4 // foo 는 함수명, 숫자는 매개변수 크기의 합 __cdecl 는 하지 않는다
4. VC 에서 만들어진 dll 을 다른 언어에서 불러쓰는 방법
4.1. __stdcall 로 만들어진 함수를 불러쓰고 싶을 경우
아래와 같은 함수가 dll 에 있다고 하자 long __stdcall foo(long param) { return param; }
dll 의 .def 파일에서 맹글링되지 않은 이름을 내보내게 해준다 EXPORTS foo @1
C 에서 불러쓰고 싶을 경우엔 아래와 같이 한다 void main() { HMODULE hDll = LoadLibrary("C:\\MyDll.dll"); if (hDll) { void (*pf)(long) = (void (*)(long))GetProcAddress(hDll, "foo"); printf("%d", pf(-1)); FreeLibrary(hDll); } }
VB 에선 아래와 같이 한다 Declare Function foo Lib "C:\MyDll.dll" (ByVal nParam As Long) As Long // 모듈 Private Sub Command1_Click() // 폼 MsgBox foo(-1) End Sub
def 파일 없이 extern "C" __declspec(dllexport) 로 정의되어 맹글링된 함수라면 맹글링된 이름을 직접 알아내서 호출할 수도 있다 C:\>dumpbin /exports "C:\MyDll.dll"
C 에서 직접 불러올 경우 GetProcAddress(hDll, _foo@4);
VB 에서 직접 불러올 경우 Declare Function foo Lib "C:\MyDll.dll" Alias "_foo@4" (ByVal nParam As Long) As Long // 모듈
4.2. __cdecl 로 만들어진 함수를 불러쓰고 싶을 경우
아래와 같은 함수가 dll 에 있다고 하자 long __cdecl foo(long);
C 에서 불러쓰고 싶을 경우엔 extern "C" __declspec(dllexport) 로 정의하면 맹글링되지 않으므로 def 없이도 __stdcall 일 경우와 동일하게 사용할 수 있다
VB 에서는 사용할 수 없다 |