>  기사  >  백엔드 개발  >  C에서 멤버 함수에 대한 포인터로 void*를 안전하게 캐스팅하는 방법은 무엇입니까?

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

Patricia Arquette
Patricia Arquette원래의
2024-10-28 06:07:30571검색

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

캐스팅의 어려움: Void* 및 멤버 함수에 대한 포인터

프로그래밍 영역에서 서로 다른 데이터 유형 간의 캐스팅은 종종 문제를 야기합니다. 특히 멤버 함수에 대한 포인터를 다룰 때. 이 기사에서는 Lua 인터프리터와 인터페이스하는 C 라이브러리를 만들려고 시도하는 동안 발생한 문제에 대해 자세히 설명합니다. 여기서 void*를 멤버 함수에 대한 포인터로 변환하는 것이 심각한 장애물이 되었습니다.

문제의 코드는 C 개체를 LuaObject로 지정하고 해당 개체에 멤버 함수를 추가합니다.

template <class T>
LuaObject<T> lobj = registerObject(L, "foo", fooObject);
lobj.addField(L, "bar", &amp;Foo::bar);

그러나 문제를 일으키는 다음 함수는 다음과 같습니다.

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

    (obj->*method)(lua_tointeger(L, 2), lua_tointeger(L, 3));
    return 0;
}

문제는 컴파일러의 불만 사항에 있습니다. void를 멤버 함수에 대한 포인터로 캐스팅할 수 없습니다. 멤버에 대한 포인터는 구체적이며 void와 같은 일반 포인터로 직접 변환할 수 없습니다.

이 문제를 해결하려면 멤버에 대한 포인터를 사용하는 대신 멤버 함수를 일반 함수로 래핑하는 것이 해결책입니다. 이 접근 방식에는 개체를 첫 번째 인수로 받아들이고 멤버 함수를 내부적으로 호출하는 자유 함수를 생성하는 작업이 포함됩니다.

다음은 이 접근 방식을 사용하여 함수의 수정된 버전입니다.

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;
}

래핑하여 멤버 함수를 사용하면 void*를 멤버 함수에 대한 포인터로 캐스팅할 필요가 없으므로 이 두 데이터 유형 사이를 캐스팅하는 동안 발생하는 문제를 해결합니다.

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

성명:
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.