2011-11-01 3 views
0

공용 API가있는 sdk.h 헤더 파일과 구현 된 컴파일 된 DLL로 구성된 SDK를 만들고 싶습니다.SDK API에서 enum params 및 반환 값을 사용하는 것이 안전합니까?

If the code looks like: 
////////// 
// sdk.h 
////////// 

enum eAction 
{ 
    Action1, 
    Action2, 
    Action3 
}; 


class Item 
{ 
protected: 
    virtual ~Item(){} 
public: 
    virtual void Do(eAction action) = 0; 
    virtual void Release() = 0; 
}; 

extern "C" 
{ 
    Item * CreateItem(); 
} 


////////// 
// sdk.cpp 
////////// 

class ItemImpl: public Item 
{ 
public: 

    virtual void Do(eAction action) 
    { 
     printf("%d", (int)action); 
     // do something 
    } 

    virtual void Release() 
    { 
     delete this; 
    } 
}; 


Item * CreateItem() 
{ 
    return new ItemImpl; 
} 


////////// 
// main.cpp client side 
////////// 

int main(int argc, char* argv[]) 
{ 
    Item *pItem = CreateItem(); 

    pItem->Do(Action1); 

    pItem->Release(); 

    return 0; 
} 

// The file sdk.h is the public API. 
// The file sdk.cpp is the implementation and it is compiled to sdk.dll. 
// The file main.cpp is the client code that uses the SDK. 

내 질문은 :

이 열거 PARAMS를 사용하고 공개 API에 값을 반환 안전한가요 (방법 음주 (조치는)) SDK 및 클라이언트 코드는 다른 컴파일러로 컴파일하는 경우? 예를 들어 SDK는 VC로 컴파일되고 클라이언트 코드는 gcc로 컴파일됩니다. 다른 컴파일러가 다른 크기 (2,4 또는 8 바이트)를 사용하여 열거 형을 나타낼 수 있습니까?

+0

다른 크기가 표준에서 허용됩니다. 중요한 문제 (이 답변에 대해 모르므로이 내용은 주석입니다)는 관심있는 플랫폼의 C++ ABI (s)와 열거 형의 기본 유형을 결정하는 방법. 어떤 플랫폼이 좋을지 모른다면, ABI의 일부가 아닌 ABI의 일부로 처리해야하므로 실행 가능한 경계를 넘어서는'enum '을 전달할 수 없습니다. std :: 문자열'. –

+0

이것이 실제 충돌의 예라고 생각합니다. http://osdir.com/ml/android-ndk/2010-10/msg00559.html. 게시물이 사실이라고 가정 할 때, 안드로이드의 toolchain은 기본적으로 가능한 한 짧은 enum을 사용하도록 설정되어 있지만, 일부 libstdC++ dll은 적어도 int를 사용합니다. 따라서'-fno-short-enums '로 컴파일하지 않는다면'short'에 맞는 enum은 두가지 사이에 호환되지 않습니다. 따라서 "두 컴파일러"가 모두 GCC이지만'-fshort-enums '이없는 컴파일러 인 경우 잠재적으로 안전하지 않을 수 있습니다. 'int'보다 작은 매개 변수가'int'로 전달되면 여러분은 그것을 벗어날 수 있습니다. –

답변

0

다른 컴파일러가 enum에 다른 크기를 줄 수도 있지만 좋은 디자인을 위해서는 중요하지 않습니다. 제 말은 ... 다른 플랫폼에서 크기가 다르기 때문에 int을 사용하는 것을 멈추지 않을 것입니다.

편집 :

같은 크기의 당신의 유형을 주장 할 경우 int32 대신 enum의를 사용합니다. enum이 모든 플랫폼에서 동일한 크기를 유지할 수있는 방법은 없습니다 (최소한 휴대용 방식).

+0

공용 API에서 int를 사용하지 않습니다. 나는 int32_t와 같은 타입을 사용한다. "좋은 디자인"이 무슨 뜻인지는 모르겠지만, 주요 목표는 다른 컴파일러와 함께 사용할 때 작동하는 코드입니다. – user1017802

+0

좋은 디자인에서는 returnValue == Action1과 같은 것을 사용하므로 저장 공간이 중요하지 않습니다. 왜 이걸 걱정하니? –

+0

열거 형은 메서드의 매개 변수이므로 저장소가 중요합니다. 한 컴파일러는 입력 매개 변수를 스택에 푸시하는 코드를 생성하고 다른 컴파일러는 스택에서 매개 변수를 팝하는 코드를 생성합니다. 첫 번째 컴파일러가 enum을 2 바이트로 처리하고 두 번째 컴파일러가 enum을 4 바이트로 위협하면 코드가 올바르게 작동하지 않을 것이라고 예상합니다 (충돌). – user1017802

0

제 생각에는 컴파일러에서 열거 형을 나타내는 최종 크기를 선택할 수 있지만 사용하지 않는 값을 ActionForceDword = 0xFFFFFFFF으로 정의하여 크기를 최소화 할 수도 있습니다.

매개 변수를 정수 유형으로 선언 할 수 있습니다. 그러나 주어진 유형의 크기에 동의하는 컴파일러는 여전히 자비를 베풀고 있습니다.

관련 문제