|
김준한 님이 쓰신 글 :
: 아래 질문에 답해주신 개박살.U&I 님께 감사드립니다.
:
: 아래질문에 이어서 또다른 질문을 드립니다.
:
: // 아래와 같이 선언된 라이브러리 함수 가 있는데요...
: VCCCALL CallbackFunction(void (* pcbfptr)(int dNum,int pNum, int Message));
:
: // RunNext라는 함수를 만들고...
: void __fastcall TMDIChild::RunNext(int dNum, int pNum, int Message)
: {
: 생략....
: }
:
: void __fastcall TMDIChild::BitBtnStartClick(TObject *Sender)
: {
: ...
:
: CallbackFunction(RunNext); // 인자로 RunNext()의 포인터를 넘겨주어야함.
: }
:
: 위와같이 하면 'Cannot convert 'void (__fastcall*(_closure)(int,int,int))(int,int,int)' to void(*)(int,int,int)' 라는 에러메시지가 나옵니다.
: RunNext를 일반함수로 만들면 되지만 그러면 MDIChild내의 컴포넌트를 액세스 하기가 나쁘고요.
:
: 이런것이 가능 할까요?
:
: 꼭 답좀 해주세요.
유엔아이 현입니다요~
일단 결론은 불가능 합니다.
이유는 클래스 내부에 있는 멤버 함수는 그 클래스 객체가 생성 되어있다는 전제가 없으므로
멤버 함수의 포인터는 존제 하지 않는 포인터 입니다.
따라서 클래스 객체가 생성 되고 난후엔 그 멤버 함수가 포인터를 갖게 되는거지요~
그런데 이런 포인터를 가지고 콜백 함수 같은곳에 대입 할려고 하면
컴파일러가 막아 버리는 것이지요~
따라서 불가능 하구요~ (가능 할수도 있는데 이건 컴파일러를 속일수 있는 고도에 기술이 ..^^;;)
암튼 그런 이유로 불가능 하구요~
굳이 그렇게 하시겠다면 방법이 또 하나 있습니다.
멤버 함수를 static 함수로 만드시면 됩니다.
멤버 함수를 static 으로 만들게 되면 전역에 있는 일반 함수와 같이
그함수는 클래스 객체의 존재여부를 떠나서 그 함수의 포인터가 존재 합니다.
정적 함수 인것이지요~
그러나, 단점은 그렇게 만들어진 static 멤버 함수는 전역에 있는 함수와 똑 같이 짜야 합니다.
그말은 곧 .. 클래스의 멤버 객체를 직접적으로 접근 할수 있는 방법이 없이 전역 함수를
짤때처럼 ,, 객체의 포인터를 가지고 가야 합니다.
this-> 는 불가능 한것이지요,, 단 한가지 이점은 ...전역 함수를 클래스 멤버로 등록 할수
있는다는 점이지요~~
그럼 대충 답변이 된것 같지요~~~
여담으로~~
비주얼씨에서 쓰래드 객체를 만드때콜백 함수를 어떻게 클래스 내부에 포함시키느냐하는 문제에서
이런 점에 부딛친적이 있습니다.
비주얼씨는 쓰래드 클래스가 매우 빈약 해서 API 를 이용해서 쓰래드를 만드는데
이렇게 되면 어떤 객체를 클래스로 디자인 하는데 있어서는 미관상 아주 짜증 납니다.
전역 함수를 만들고 나머진 클래스로 만들고 보기가 않좋지여~
그래서 사용한 방법이 static 함수 였습니다.
그 방법 밖엔 없더군요 하지만 빌더는 완벽하게 쓰래드 클래스를 포장하고 있어서
그냥 멤버 함수를 짜면 해결이 되더군요~~
빌더 만만세~~
그럼 도움 되셨기를..............
|