> 백엔드 개발 > C++ > 본문

C에서 'void*'와 멤버 함수에 대한 포인터 사이를 안전하게 캐스팅하는 방법은 무엇입니까?

Linda Hamilton
풀어 주다: 2024-10-27 20:06:02
원래의
265명이 탐색했습니다.

How to Safely Cast Between `void*` and a Pointer to a Member Function in C  ?

void*와 멤버 함수에 대한 포인터 사이의 캐스팅

C 프로그래밍 세계에서 void*와 멤버 함수에 대한 포인터 사이의 캐스팅 멤버 함수는 정말 골치 아픈 일이 될 수 있습니다. 이 문제를 설명하는 특정 문제를 살펴보겠습니다.

다음 코드 조각을 고려하세요.

<code class="cpp">template <class T>
int call_int_function(lua_State *L) 
{
    void (T::*method)(int, int) = reinterpret_cast<void (T::*)(int, int)>(lua_touserdata(L, lua_upvalueindex(1))); // <-- problematic line
    T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));

    (obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3));
    return 0;
}</code>
로그인 후 복사

여기서 GCC는 void*에서 void(T::*)로의 캐스트에 대해 불평합니다. (int, int)가 유효하지 않습니다. 그렇다면 해결책은 무엇입니까?

문제 이해

문제를 이해하려면 멤버 함수에 대한 포인터의 특성을 더 깊이 파고들어야 합니다. 주소를 가리키는 일반 포인터와 달리 멤버 함수에 대한 포인터는 훨씬 더 복잡합니다. 여기에는 컴파일러 구현 및 클래스 멤버의 레이아웃과 관련된 정보가 포함되어 있습니다.

대체 접근 방식

사실 void*를 포인터에 직접 캐스팅할 수는 없습니다. 멤버 함수에. 제안된 솔루션은 멤버 함수를 일반 함수로 래핑하고 대신 반환하는 것입니다. 방법은 다음과 같습니다.

<code class="cpp">template <class T>
int call_int_function(lua_State *L) 
{
    void (*method)(T*, int, int) = reinterpret_cast<void (*)(T*, int, int)>(lua_touserdata(L, lua_upvalueindex(1)));
    T *obj = reinterpret_cast<T *>(lua_touserdata(L, 1));

    method(obj, lua_tointeger(L, 2), lua_tointeger(L, 3));
    return 0;
}</code>
로그인 후 복사

이제 void*에 저장하고 문제 없이 검색할 수 있는 일반 함수 포인터로 캐스팅하고 있기 때문에 이 접근 방식이 효과적입니다.

위 내용은 C에서 'void*'와 멤버 함수에 대한 포인터 사이를 안전하게 캐스팅하는 방법은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

원천:php.cn
본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.
저자별 최신 기사
인기 튜토리얼
더>
최신 다운로드
더>
웹 효과
웹사이트 소스 코드
웹사이트 자료
프론트엔드 템플릿