2012-06-12 2 views
1

콜백 기반 C API가있는 C++ 라이브러리가 있습니다.사용자 데이터로 엄격한 앨리어싱 및 콜백

typedef struct {...} Result; 
typedef void (*callback) (const Result* result, void* userData); 

사용자가이 같은 콜백을 등록 할 수 있으며, 임의의 데이터에 대한 포인터를 설정할 수 있으며,이 라이브러리는 다시 그 포인터를 전달 콜백 물마루 것이다 콜백 유형은 다음과 같다.

내 관심사는 다음과 같습니다. 엄격한 앨리어싱 규칙을 위반했는지 여부입니다. userData의 유형을 char *로 변경해야합니까?

+0

어떻게 콜백을 등록 하시겠습니까? – jxh

+0

왜 이것이 엄격한 앨리어싱 규칙을 어기는 것입니까? 컴파일러 오류가 발생합니까? 어떤 종류? 무슨 컴파일러? – kebs

+0

@kebs : 컴파일러 오류가 없으면 엄격한 앨리어스 위반이 발생하지 않습니다. 질문자는 규칙을 다소 오해하고 있으며, 코드에 UB의 원인을 알 수없는 것을 두려워합니다. 그것에 대해 묻는 것은 현명한 것 같습니다. –

답변

4

아니요, 포인터가 간접적 인 경우에만 별칭이 적용되며 포인터가 포인터 값으로 전달되는 경우에는 적용되지 않습니다. 사용자가 일관되게 행동하는 한 괜찮을 것입니다.

즉, 실제 유형이 TuserData을 전달하는 경우 사용자는 콜백 함수에 액세스하기 전에 항상 T *으로 캐스팅해야합니다.

다시 포인터로 액세스하는 경우 (예 : printf("DEBUG: %p", userData)) 괜찮 으면서도 라이브러리에 userData을 간접적으로 삽입하지 않았다고 가정합니다.

0

C 콜백 API에 대해 더 많은 "C++"- ish 인터페이스를 만들면 별칭 문제를 제거 할 수 있습니다.

struct Callback { 
    void (*callback) (Callback *cb_this, const Result *result); 
}; 

같은 것을 할 것 콜백을 등록하려면 C 콜백 API를 사용하는 C 프로그래머 :

struct MyCallback { 
    struct Callback cb; 
    int x; 
    double y; 
    /* ... */ 
}; 

void my_callback_func (Callback *cb_this, const Result *result) { 
    MyCallback *my_cb = (MyCallback *)cb_this; 
    /* ... */ 
} 

MyCallback mycb = { { my_callback_func }, 0, 0, /* ... */ }; 

당신이 void * 처리에 대해 걱정할 필요가 없습니다 이쪽으로. 대신 Callback에 대한 단일 포인터가 전달됩니다.

+0

@SteveJessop : C++에서는 좋지 않지만, OP에서는 C++에서 구현 된 C 콜백 API가 있다고합니다. – jxh

+0

@SteveJessop : 콜백 API를 사용하는 C 프로그래머를위한 대답을 명시했습니다. 고마워, 안부. – jxh

+0

아, 고마워. 고마워. 어떤 이유로 나는 당신이 C와 유사한 API의 C++ 사용자에 대해 이야기하고 있다고 생각했습니다. –

관련 문제