장성호 님이 쓰신 글 :
: C++Builder는 class의 멤버함수 type define 하는 방식 좀 다릅니다.
:
: 아래 예제에서 쓴 TThreadMethod 의 typedef를 찾아보십시요
: Classes.hpp 파일에 보면 아래와 같이 선언되어있습니다.
: typedef void __fastcall (__closure *TThreadMethod)(void);
:
:
: aisi c++과 뭔가 다른것이 보입니까?
: 키워드 __closure 이 보입니까? 이것이 핵심입니다.
: __closure 키워드는 C++Builder에서 확장된것입니다.
:
: 아래 링크에 설명이 있습니다.
:
http://www.borlandforum.com/impboard/impboard.dll?action=read&db=bcb_tip&no=105
:
:
: 정리하면 C++Builder에서는 class 멤버 함수의
: 포인터 타입선언은 __closure 를 이용해 선언합니다.
:
: typedef int __stdcall ( *TSetMapStatus)(int istatus); // 보통은 이렇게 하지만
: typedef void __stdcall (__closure *TMemberMethod)(TObject *Sender); // 멤버함수는 이렇게 합니다.
:
:
: 두함수의 size를 확인해 보면
: void __fastcall TForm1::Button3Click(TObject *Sender)
: {
: ShowMessage(sizeof(TSetMapStatus)); // 4 Byte
: ShowMessage(sizeof(TMemberMethod)); // 8 Byte
: }
:
: win32에서 포인터는 대게 32bit 즉 4Byte인데
: __closure 키워드로 타입을 선언하면 8Byte가 됩니다.
:
: 위에 링크를 따라가보면 설명되어있지만
: 앞에 4Byte는 함수주소이며 , 뒤쪽에 4Byte는 class object 주소가 저장됩니다.
:
:
: 그럼....
:
:
:
:
:
: 신우철 님이 쓰신 글 :
: : 매번 답변 감사합니다
: : 하지만 이렇게는 해봤구요 문제는
: : 밑에 소스 있는 부분에서
: : proc= FormThreadProc; 이 부분에서
: : [C++ Error] IOCPSWin.cpp(202): E2235 Member function must be called or its address taken
: : 이런 에러가 떨어집니다 멤버 함수는 함수 포인터를 넘길수 없다는 에러인데
: : 그래서 제가 했던 부분이 typedef void(CIOCP::*proc)(void);
: : 이렇게 선언을 한거구요 님께서 샘플로 만들어 주신 소스는 제가 처음 코드작성시 다 해봤던 거구요
: : 만약 밑에 소스가 실행이 된다면 어떻게 되는지 궁금합니다
: : 분명 CBuiler에서는 맴버함수의 포인터를 넘길수 없다고 들었는데요
: :
: :
: : 장성호 님이 쓰신 글 :
: : : 지난번 하신 질문의 답변을 잘 읽어보시면 답이 있습니다.
: : : 그리고 여기 검색해 봐도 나오구요
: : :
: : : 간단한 샘플 만들어서 올립니다. 참조하세요
: : :
: : : //===================Unit2.h 파일 ==============================================
: : : #ifndef Unit2H
: : : #define Unit2H
: : : //---------------------------------------------------------------------------
: : : #include <Classes.hpp>
: : : //---------------------------------------------------------------------------
: : : class TMyThread : public TThread
: : : {
: : : private:
: : : TThreadMethod Proc;
: : : protected:
: : : void __fastcall Execute();
: : : public:
: : : __fastcall TMyThread(bool CreateSuspended);
: : : __fastcall TMyThread(bool CreateSuspended,TThreadMethod proc);
: : : void __fastcall TMyThread::SetProcess(TThreadMethod proc);
: : :
: : : };
: : : //---------------------------------------------------------------------------
: : : #endif
: : :
: : :
: : :
: : :
: : : //===================Unit2.cpp 파일 ==============================================
: : : #include <vcl.h>
: : : #pragma hdrstop
: : :
: : : #include "Unit2.h"
: : : #pragma package(smart_init)
: : : //---------------------------------------------------------------------------
: : :
: : : __fastcall TMyThread::TMyThread(bool CreateSuspended)
: : : : TThread(CreateSuspended)
: : : {
: : : Proc=NULL;
: : : }
: : : //---------------------------------------------------------------------------
: : : __fastcall TMyThread::TMyThread(bool CreateSuspended,TThreadMethod proc)
: : : : TThread(CreateSuspended)
: : : {
: : : Proc=proc;
: : : }
: : : //---------------------------------------------------------------------------
: : : void __fastcall TMyThread::SetProcess(TThreadMethod proc)
: : : {
: : : Proc=proc;
: : : }
: : : //---------------------------------------------------------------------------
: : : void __fastcall TMyThread::Execute()
: : : {
: : : FreeOnTerminate = true;
: : : if(Proc) Synchronize(Proc);
: : : }
: : :
: : :
: : : //===================Unit1.cpp 파일 ==============================================
: : :
: : : void __fastcall TForm1::FormThreadProc(void )
: : : {
: : : ShowMessage("잘되나?");
: : : }
: : : //---------------------------------------------------------------------------
: : : #include "Unit2.h"
: : : void __fastcall TForm1::Button1Click(TObject *Sender)
: : : {
: : : TThreadMethod proc;
: : : proc= FormThreadProc;
: : : TMyThread *tred=new TMyThread(false,proc);
: : : }
: : : //---------------------------------------------------------------------------
: : :
: : :
: : : 그럼....
: : :
: : :
: : : 신우철 님이 쓰신 글 :
: : : : 하루를 꼬박 생각해도 답이 없네요 ㅜㅜ
: : : : 질문할 사항은 제가 IOCP를 만들고자 합니다 winsock2.h를 사용해서 말이죠
: : : : 그런데 문제는 쓰레드 생성입니다
: : : : 일단 소스를 보시면
: : : :
: : : : ------------------------------------------------------------------------
: : : : IOCP.h
: : : : ------------------------------------------------------------------------
: : : : #include ListenThread.h
: : : : class CIOCP
: : : : {
: : : : public:
: : : : sock m_client;
: : : : CListenThread *m_pListen;
: : : : void Init();
: : : : void LitenProc();
: : : : }
: : : : ------------------------------------------------------------------------
: : : :
: : : :
: : : :
: : : :
: : : : ------------------------------------------------------------------------
: : : : CIOCP.cpp
: : : : ------------------------------------------------------------------------
: : : : void CIOCP::Init()
: : : : {
: : : : m_pListen = new CListenThread();
: : : : m_pListen->setproc(&CIOCP::LitenProc)
: : : : }
: : : : void LitenProc()
: : : : {
: : : : while(true)
: : : : {
: : : : if(FD_ACCEPT)
: : : : {
: : : : m_client = ACCEPT();
: : : : .
: : : : .
: : : : .
: : : : }
: : : : }
: : : : }
: : : : ------------------------------------------------------------------------
: : : :
: : : :
: : : :
: : : :
: : : : ------------------------------------------------------------------------
: : : : ListenThread.h
: : : : ------------------------------------------------------------------------
: : : : #include IOCP.h
: : : : typedef void(CIOCP::*proc)(void);
: : : : class CListenThread :public TThread
: : : : {
: : : : public:
: : : : proc m_proc;
: : : : void setproc(proc pproc);
: : : :
: : : : }
: : : : ------------------------------------------------------------------------
: : : :
: : : :
: : : :
: : : :
: : : : ------------------------------------------------------------------------
: : : : ListenThread.cpp
: : : : ------------------------------------------------------------------------
: : : : void CListenThread::setproc(proc pproc)
: : : : {
: : : : m_proc = pproc;
: : : : }
: : : :
: : : : void __fastcall CListenThread::Excute()
: : : : {
: : : : (CIOCP->*m_proc)();
: : : : }
: : : : ------------------------------------------------------------------------
: : : :
: : : : 이렇게 할려고 하는데 결국은 두개의 파일에서 참조를 해야하고 그렇게 되면 상호참조
: : : : (typedef void(CIOCP::*proc)(void);)에러가 떨어집니다
: : : : 도저히 답이 없네요 결국은 CreateThread 를 사용해야 하는것 같은데 거기에 들어가는
: : : : Thread함수 또한 DWORD WINMAIN 함수네임() 이렇게 선언을 해야 하고 이함수가 CIOCP 클래스
: : : : 내에서 선언을 하면 에러가 나더라고요 뭐 좋은 방법이 없을까요
: : : : 고맙게도 많은 분들이 여기에 답변을 주셨는데 제가 원하는 답변이 아니라서 자세히 소스와 함께
: : : : 다시 올립니다
: : : : 다시 한번 말씀드리자면 제가 원하는건 쓰레드 클래스를 하나 만들고 그 쓰레드 클래스 내에서
: : : : 즉 Excute() 내에서 작업을 하는게 아니고 메인클래스에서 쓰레드 작업을 하고 싶은겁니다
: : : : 이렇게 하는 이유는 모든 작업들에 필요한 변수들은 CIOCP 클래스에 선언이 되어 있으니까요
: : : : 그렇다고 CIOCP 에서 쓰레드를 상속받을수도 없죠 다중 쓰레드를 생성 할거니까요
: : : : 제발 좋은 방법이 없을까요 깔끔하고 안정적인 그런 방법이요 부탁좀 드립니다
: : : :
: : : : 아 그리고 또 한가지 질문이 있는데 제가 프로젝트에 C++Builder 6.0에서 작업을 하는데
: : : : 위에 파일 네임이 있잖아요 탭으로 거기에 CIOCP.cpp CIOCP.h 이렇게 두개의 텝이 있는데
: : : : 원래대로라면 하나의 탭에서 Ctl + F6를 누르면 한텝에서 CIOCP.cpp CIOCP.h 이게 두개 번갈아 가면서 보여야
: : : : 하는거 아닌가요 왜 저는 두개의 텝으로 나오나요??
: : : : 이상 허접한 질문이었습니다 답변 꼭 부탁 드립니다