Life (삶)/컴퓨터 관련

VC++로 만든dll을 vb에서 사용하기

험한 세상에서 홀로 살아가는 나그네 2008. 2. 18. 17:53

아래는 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 에서는 사용할 수 없다