다음을 통해 공유


__declspec(dllimport)을 사용해 함수 호출 가져오기

__declspec(dllimport)을 사용하여 호출에 주석을 달면 호출이 더 빨라질 수 있습니다. __declspec(dllimport)은 내보낸 DLL 데이터에 액세스할 때 항상 필요합니다.

DLL에서 함수 가져오기

다음 코드 예제에서는 __declspec(dllimport)을 사용하여 DLL의 함수 호출을 애플리케이션으로 가져오는 방법을 보여줍니다. func1main 함수를 포함하는 실행 파일과는 별도의 DLL에 있는 함수라고 가정합니다.

이 코드에서 __declspec(dllimport)이 없는 경우:

int main(void)
{
   func1();
}

컴파일러는 다음과 같은 코드를 생성합니다.

call func1

그리고 링커는 호출을 다음과 같이 변환합니다.

call 0x4000000         ; The address of 'func1'.

다른 DLL에 func1이 있으면 링커는 func1의 주소를 알 수 없기 때문에 이 주소를 직접 확인할 수 없습니다. 32비트 및 64비트 환경에서 링커는 알려진 주소에 썽크를 생성합니다. 32비트 환경에서 썽크는 다음과 같습니다.

0x40000000:    jmp DWORD PTR __imp_func1

여기서 __imp_func1은 실행 파일의 가져오기 주소 테이블에 있는 func1 슬롯의 주소입니다. 이러한 모든 주소는 링커에게 알려집니다. 모든 것이 제대로 작동하도록 로더는 로드 시 실행 파일의 가져오기 주소 테이블을 업데이트하기만 하면 됩니다.

따라서 __declspec(dllimport)을 사용하는 것이 좋습니다. 썽크가 필요 없는 경우에는 링커가 썽크를 생성하지 않기 때문입니다. 썽크로 인해 코드가 더 커져(RISC 시스템에서는 몇 가지 명령일 수 있음) 캐시 성능이 저하될 수 있습니다. 컴파일러에게 이 함수가 DLL에 있음을 알려주면 컴파일러가 간접 호출을 생성할 수 있습니다.

따라서 이 코드는

__declspec(dllimport) void func1(void);
int main(void)
{
   func1();
}

이러한 명령을 생성합니다.

call DWORD PTR __imp_func1

썽크가 없고 jmp 명령이 없으므로 코드가 더 작고 더 빠릅니다. 전체 프로그램 최적화를 사용하여 __declspec(dllimport) 없이 동일한 효과를 얻을 수도 있습니다. 자세한 내용은 /GL(전체 프로그램 최적화)을 참조하세요.

DLL 내 함수 호출의 경우 사용자는 간접 호출을 사용하지 않아도 되기를 바랍니다. 링커는 함수의 주소를 이미 알고 있습니다. 간접 호출 전에 함수의 주소를 로드하고 저장하는 데 추가 시간 및 공간이 필요합니다. 직접 호출은 항상 더 빠르고 더 작아야 합니다. 사용자는 DLL 자체의 외부에서 DLL 함수를 호출하는 경우에만 __declspec(dllimport)를 사용하기를 원합니다. DLL을 빌드할 때 해당 DLL 내 함수에 __declspec(dllimport)을 사용하지 마세요.

참고 항목

애플리케이션으로 가져오기