일반 규칙 및 제한 사항

Microsoft 전용

  • 또는 특성 없이 함수 또는 개체를 dllimportdllexport 선언하는 경우 함수 또는 개체는 DLL 인터페이스의 일부로 간주되지 않습니다. 따라서 해당 모듈 또는 같은 프로그램의 다른 모듈에 함수 또는 개체의 정의가 있어야 합니다. 함수 또는 개체를 DLL 인터페이스의 일부로 만들려면 다른 모듈에서 함수 또는 개체의 정의를 다음과 같이 dllexport선언해야 합니다. 그렇게 하지 않으면 링커 오류가 생성됩니다.

    특성을 사용하여 함수 또는 개체를 dllexport 선언하는 경우 해당 정의가 동일한 프로그램의 일부 모듈에 표시되어야 합니다. 그렇게 하지 않으면 링커 오류가 생성됩니다.

  • 프로그램의 단일 모듈에 동일한 함수 또는 개체 dllexport 에 대한 선언과 dllexport 둘 다 dllimport 포함된 경우 특성이 특성보다 dllimport 우선합니다. 그러나 이 경우 컴파일러 경고가 생성됩니다. 예시:

    __declspec( dllimport ) int i;
    __declspec( dllexport ) int i;   // Warning; inconsistent;
                                     // dllexport takes precedence.
    
  • C++에서는 전역적으로 선언되거나 정적 로컬 데이터 포인터를 초기화하거나 특성을 사용하여 선언된 dllimport 데이터 개체의 주소를 사용하여 초기화하여 C에서 오류를 생성할 수 있습니다. 또한 특성으로 선언된 함수의 주소를 사용하여 정적 로컬 함수 포인터를 초기화할 dllimport 수 있습니다. C에서는 이러한 대입으로 인해 포인터가 함수의 주소 대신 DLL 가져오기 썽크(함수로 제어를 전송하는 코드 스텁)의 주소로 설정됩니다. C++에서는 포인터가 함수의 주소로 설정됩니다. 예시:

    __declspec( dllimport ) void func1( void );
    __declspec( dllimport ) int i;
    
    int *pi = &i;                             // Error in C
    static void ( *pf )( void ) = &func1;     // Address of thunk in C,
                                              // function in C++
    
    void func2()
    {
       static int *pi = &i;                  // Error in C
       static void ( *pf )( void ) = &func1; // Address of thunk in C,
                                             // function in C++
    }
    

    그러나 개체 선언에 특성을 포함하는 dllexport 프로그램은 프로그램 어딘가에 해당 개체에 대한 정의를 제공해야 하므로 함수의 주소를 사용하여 전역 또는 로컬 정적 함수 포인터를 dllexport 초기화할 수 있습니다. 마찬가지로 dllexport 데이터 개체의 주소로 전역 또는 로컬 정적 데이터 포인터를 초기화할 수 있습니다. 예를 들어, 다음 코드는 C 또는 C++에서 오류를 발생시키지 않습니다.

    __declspec( dllexport ) void func1( void );
    __declspec( dllexport ) int i;
    
    int *pi = &i;                              // Okay
    static void ( *pf )( void ) = &func1;      // Okay
    
    void func2()
    {
        static int *pi = &i;                   // Okay
        static void ( *pf )( void ) = &func1;  // Okay
    }
    
  • 기본 클래스로 표시되지 dllexport않은 일반 클래스에 적용 dllexport 하는 경우 컴파일러는 C4275를 생성합니다.

    컴파일러는 기본 클래스가 클래스 템플릿의 특수화인 경우 동일한 경고를 생성합니다. 이 문제를 해결하려면 기본 클래스를 .로 dllexport표시합니다. 클래스 템플릿의 특수화 문제는 클래스 템플릿을 표시할 수 없는 위치를 지정 __declspec(dllexport)하는 것입니다. 대신 클래스 템플릿을 명시적으로 인스턴스화하고 이 명시적 인스턴스화를 .로 dllexport표시합니다. 예시:

    template class __declspec(dllexport) B<int>;
    class __declspec(dllexport) D : public B<int> {
    // ...
    

    템플릿 인수가 파생 클래스일 경우 이 해결 방법은 실패합니다. 예시:

    class __declspec(dllexport) D : public B<D> {
    // ...
    

    템플릿의 일반적인 패턴이므로 컴파일러는 하나 이상의 기본 클래스가 있는 클래스에 적용되는 경우와 하나 이상의 기본 클래스가 클래스 템플릿의 특수화인 경우의 의미 체계 dllexport 를 변경했습니다. 이 경우 컴파일러는 클래스 템플릿의 특수화에 암시적으로 적용 dllexport 됩니다. 다음을 수행하고 경고를 받을 수 없습니다.

    class __declspec(dllexport) D : public B<D> {
    // ...
    

Microsoft 전용 종료

참고 항목

dllexport, dllimport