12편: SOUI의 utilities 모듈을 DLL로 컴파일하는 이유는 무엇입니까?

3211 단어 util
SOUI가 DuiEngine에 비해 중요한 변화는 많은 모듈이 하나의 DLL로 바뀌었다는 것이다.
그리고 많은 상황에서 사용자들은 전체 제품이 EXE가 되기를 원할 수도 있다. 원래는 DuiEngine이 LIB 컴파일 모드를 제공했는데 이때 LIB 모드의 DuiEngine를 연결하면 된다.
그러나 SOUI 기본값은 최소한 Utilities 모듈에서는 LIB 컴파일 모드를 제공하지 않습니다.
utilities가 기본적으로 DLL 컴파일만 제공하는 이유는 Sstring 클래스가 utilities에서 이루어졌기 때문입니다.
문자열은 컴파일링에서 가장 흔히 볼 수 있는 기본 대상 중의 하나이다.라이브러리 (CRT) 동적 컴파일 (MD, MDd) 에서 이것은 문제가 아니다. 모든 모듈의 메모리 분배는 같은 라이브러리 (CRT) 에서 이루어지기 때문에 서로 다른 모듈 사이에서 대상을 전달하는 것은 상대적으로 간단하기 때문이다.프로젝트가 라이브러리 정적 컴파일링(MT or MTd)을 사용하면 서로 다른 모듈 사이에서 문자열 대상을 전달하는 것은 매우 어렵다. 자칫 A 모듈에서 분배된 문자열 대상이 B 모듈에 방출되기 때문이다.
utilities가 DLL 컴파일을 사용하는 것은 이 문자열 대상의 크로스 모듈 전달을 해결하기 위해서입니다.
실행 라이브러리의 동적 컴파일을 사용하는 상황은 말할 것도 없고 정적 라이브러리로 컴파일된CRT의 상황을 소개한다.
SOUI에서 사용되는 문자열 객체에는 다음과 같은 몇 가지 팁이 있습니다. 각 String 객체에는 포인터 멤버 변수가 하나씩 있습니다.
    template <class tchar, class tchar_traits>

    class TStringT

    {

    public:

        typedef tchar    _tchar;

        typedef const _tchar * pctstr;



    protected:

        tchar* m_pszData;   // pointer to ref counted string data

    };

TstringT는 템플릿 클래스이지만 SOUI에서 클래스를 내보내는 방법으로 템플릿의 두 가지 특수 클래스를 내보냅니다.
#ifdef UTILITIES_EXPORTS

#    define EXPIMP_TEMPLATE

#else

#    define EXPIMP_TEMPLATE extern

#endif



     #pragma warning (disable : 4231)



    EXPIMP_TEMPLATE template class UTILITIES_API  TStringT<char, char_traits>;

    EXPIMP_TEMPLATE template class UTILITIES_API  TStringT<wchar_t, wchar_traits>;

string 클래스를 내보내면 string의 모든 실행 코드가utilities 모듈 내부에 있음을 보증합니다. 이것은string 대상의 유일한 구성원 변수를 보장합니다.
tchar* m_pszData;
메모리 분배 및 방출은utilities 모듈에 고정되어 있습니다.
이렇게 처리함으로써 사용자가 정의한string이 어느 모듈이든 진정한 메모리 관리든utilities에서든string 대상은 서로 다른 모듈 사이에서 쉽게 전달될 수 있다.
std::string을 비교해 보면 std::string을 사용하면 서로 다른 모듈 사이에서 대상을 전달하는 것은 매우 위험합니다. std::string은 템플릿 클래스이기 때문에 그의 코드는 서로 다른 모듈로 컴파일됩니다. 즉, 서로 다른 모듈에서 std::string의 구성원 함수를 호출하여 실행하는 코드는 것이 다르기 때문입니다. 그러면 A 모듈에서 설명한string이 B 모듈에 전달되고 B 모듈에 방출되면 프로그램이 붕괴됩니다.
이것이 바로 utilities 모듈이 기본적으로 DLL 컴파일만 제공하는 이유입니다.
원인을 알면 처리하기 쉽다.
전체 프로젝트가 하나의 EXE가 되기를 희망하는 경우 utilities 모듈의 컴파일 유형을 LIB로 직접 수정하면 된다. 왜냐하면 이런 상황에서 크로스 모듈의 대상 전달 문제가 존재하지 않기 때문이다.


좋은 웹페이지 즐겨찾기