함수 포인터를 (void *) 로 형변환 했다 다시 함수포인터로...
글쓴이: icristi / 작성시간: 월, 2003/12/08 - 5:57오후
함수 포인터를 전달받는 함수를 쓰레드로 만들고 싶어서(pthread_creadte)
함수포인터를 void * 으로 형 변환 했습니다.
다시 함수 포인터로 형변환 하는 방법이 있을까요?
bool CMainThread::Create( void* (*func)(void*) ) { pthread_create( &m_hThread, NULL, &CMainThread::Run, (void*)func ); . . . void* CMainThread::Run( void* func ) { //func 를 어떻게 함수로 쓸까요? . . . }
한 가지 더요!
[root@devel dcdManager]# gcc -c MainThread.cpp MainThread.cpp: In method `bool CMainThread::Create ()': MainThread.cpp:42: ISO C++ forbids taking the address of an unqualified non-static member function to form a pointer to member function. Say `&CMainThread::Run' MainThread.cpp:42: cannot convert `void *(CMainThread::*) (void *)' to `void *(*) (void *)' for argument `3' to `pthread_create (pthread_t *, const pthread_attr_t *, void *(*) (void *), void *)'
pthread_create 에 원래 static 함수 밖에 쓰지 못하나요?
멤버 함수 &Run 을 그냥 쓰니까 저런 에러메세지가 나오네요.
static으로 바꾸니까 되긴 해요...
요즘 이것 저것 참 물어보는 것만 많네요...
KLDP에 도움이 되고자 하지만 지금 제 수준에서는 그저 이렇게
궁금증을 해소를 위한 하소연 밖에 못하네요....ㅜ.ㅜ
저도 언젠가 내공이 많이 쌓이면 왕성한~ 답변활동(?)을 통해
도움 받은 것 환원해야겠죠~~~ ^^;;[/code]
Forums:
Re: 함수 포인터를 (void *) 로 형변환 했다 다시 함수포인터로.
질문에 이미 답이 있습니다. void *(*func) (void *);
좀 멋있게 하려면,
typedef void * (*ThreadHandlerFunc) (void *);
이렇게 해서 type casting을 하면 되겠죠. 꼭 안해도 되고...
혹시나 해서 예제를 쓰면 Run에서 func이 넘어왔다면
ThreadHandlerFunc doThis = (ThreadHandlerFunc)func;
이렇게 하고 doThis((void *)&aa); 뭐 이런식으로 쓸 수 있겠죠. 그런데
꼭 이렇게 하시는 이유가 있으신지?
http://bbs.kldp.org/viewtopic.php?t=2803
http://bbs.kldp.org/viewtopic.php?t=28039
static 으로 하지 않으면 형비교에서 달라지기 때문에 넘길 수가 없습니다. 물론 강제로 casting하고, 파라메터로 넘기는 void *에 this 를 넘겨서 멤버를 호출하는 방법도 있습니다.
보기에 안좋지만 C를 하부로 사용하려면 어쩔 수 없습니다.
---
http://coolengineer.com
네임 멩글링 문제 이외에도 실제로 형이 다르지 않나요? C++ 써본지가
네임 멩글링 문제 이외에도 실제로 형이 다르지 않나요? C++ 써본지가 좀 되서
잊어버렸는데, 형이 실제로 달랐던 것 같은데... 아, 그래서 캐스팅으로 되는
것이 아니었던 것으로 기억됩니다만...
Re: 함수 포인터를 (void *) 로 형변환 했다 다시 함수포인터로.
그냥 궁금해서 그러는데요...
typedef를 쓰지 않고
ThreadHandlerFunc doThis = (ThreadHandlerFunc)func;
이 구문을 표현하는 방법은 무엇일까요?
꼭 이렇게 하는 이유는요.
다음과 같은 클래스를 설계하고자 해서 입니다.
기본적으로 쓰레드 클래스인데, 이것으로부터 객체를 만들 때
쓰레드로 실행될 임의의 함수를 함수 포인터로 전달하여 instantiation 하고자
하는 것입니다.
이런 구조가 혹 정도에 맞지 않거나 비상식적인 것은 아닌지요?
여러분들의 친절하신 답변해 항상 감사합니다.
[quote="chunsj"]네임 멩글링 문제 이외에도 실제로 형이 다르
맞습니다... static 아닌 member function은 일반함수로 상호 casting되지 않으며, static 을 사용해서 한단계 건너 뛰는 방식으로 밖에 되지 않습니다.
일반함수의 void * 에 객체의 this 를 넘겨 나중에 다시 staic 함수내에서 ((AClass *)pv)-> 이런 형태로 복원하여 접근하는 방법밖에는 되지 않습니다.
그 방법이 c 함수의 callback에 넣어 사용하는 가장 일반적인 방법으로 알고 있습니다.
이렇게 쓰는 방법을 말하려고 했는데, 짧게 인용만하려 끝내려다가.. :roll:
음.. 그런데, 왜 static 아닌 멤버함수와 일반함수는 상호 casting이 안될까요...
좀더 찾아 봐야겠습니다.
---
http://coolengineer.com
Re: 함수 포인터를 (void *) 로 형변환 했다 다시 함수포인터로.
static 혹은 전역 함수 밖에 쓸 수가 없습니다.
멤버 함수의 경우 this 포인터가 반드시 필요한데
위의 경우
&CMainThread::Run 이라고
멤버함수 포인터를 넘겨도
this 포인터를 같이 전달하는 것이 아니기 때문에
컴파일러가 오류를 내는 것이지요
만약 이런 문법이 허용된다면
CMainThread::Run() 함수가 멤버 변수에 접근하는 경우 어느 객체의 멤버에 접근하는 지를 알 수 없으므로 큰일 나게 됩니다.
정적 멤버 함수는 this 포인터를 필요로 하지 않으므로
일반 함수처럼 캐스팅이 자유롭습니다.
Re: 함수 포인터를 (void *) 로 형변환 했다 다시 함수포인터로.
인텔머신에서 C 함수의 callback function으로 C++ 클래스의 멤버함수를 사용하는 방법이 있습니다. C++ calling convention의 동작방식을 직접 구현하여 함수를 리다이렉션해주는 방법입니다. 그 방법이 재미있어서, 참고삼아 관련 URL을 올려봅니다.
단, 인텔머신이 아닌 다른 머신에서 사용하려면 코드를 수정해야 합니다.
http://www.codeproject.com/cpp/thunk.asp?print=true
아참, 위에서 제공하는 코드는 WIN32 + Visual C++ 컴파일러에 의해 동작하는 코드입니다.
이걸 리눅스 + gcc 에서 동작하도록 만들 수도 있지 않을까요?
Re: 함수 포인터를 (void *) 로 형변환 했다 다시 함수포인터로.
아래 방법처럼 하면 될듯 합니다.
friend
-,.-;; 클래스 내부에서 재정의된( 외부접근 불가한?friend??) 함수들의모임을 가지고서
, member function 으로 정의되지 않고서도 thread routine 으로 사용
되는 것을 보고 있음..
어
[quote="pynoos"][quote="chunsj"]네임 멩글링 문
저런... 오늘 아침 출근하다가.. 생각나서..
둘은 calling convention이 다른부류입니다.
하나는 일반 cdecl 이겠고, 하나는 this-call 이겠죠... calling convention이 다른 함수간의 casting은 일어나지 않습니다.
---
http://coolengineer.com
[code:1]아래의 클래스 X가 있을때class X {
모든 non-member function은 컴파일러에 의해서 implicit하게 const X* this가 첫번째 인자로 들어갑니다..
이렇게
void X::(const X*this, int a) {
}
static function은 this가 자동으로 들어가지 않지요.
그래서 casting이 안될거에요. 그리고 pthread_create의 인자로도
signature가 다르므로 사용이 될 수 없죠.. (non-static member function..)
Life rushes on, we are distracted
댓글 달기