문제

이 간단한 코드 작업을하고 싶습니다.

#include <iostream>
#include <windows.h>


    void printSome (int i)
    {
        std::cout << i << std::endl;
    }

    void spawnThread (void (*threadName)(int i))
    {
        CreateThread 
            (
                0,      // default security attributes
                0,          // use default stack size 
                (LPTHREAD_START_ROUTINE)threadName,  // thread function name
                (LPVOID)i,          // argument to thread function 
                0,          // use default creation flags 
                0       // returns the thread identifier 
            );  
    }

    int main ()
    {
        spawnThread(printSome(155));
    }

나는 Windows에 있으며, 모든 도움을 사용하는 것은 크게 걱정할 것입니다.

도움이 되었습니까?

해결책

개인적으로, 나는 당신이 매우 c ++처럼하려고하는 것처럼 함수 포인터를 통과하는 것을 고려하지 않을 것입니다. C ++에서 C를 코딩하고 있습니다

대신, 나는 그 일을 수업에서 감싸고 있습니다. 큰 장점은 매번 매개 변수를 얻기 위해 Greazy 캐스팅 트릭을 수행하지 않고 원하는 많은 회원을 갖도록 수업을 무시할 수 있습니다.

코드는 조금 길고 끝까지 밀어 넣었습니다. 그러나 그것이 당신이 할 수있는 것은 다음과 같습니다.

   class print_some : public basic_thread {
    private:
       int i;
    public:     
       print_some (int i) : i(i) {};
       action_callback () {
          std::cout << i << std::endl;
       }
    }
    int main () {
       print_some printer (155);
    }

다음은 수업 중 하나의 수용된 예제 코드입니다.

class basic_thread : 
{
public:
   basic_thread();
protected:
   unsigned long m_ThreadId;

   virtual void action_callback () {};

   // Internal routine used to bridge between OS callback format and 
   // action_callback. *Must* be static for the OS.
   static unsigned long __stdcall self_calling_callback (void *parameter);
}

... 그리고 .cpp에서 :

unsigned long __stdcall basic_thread::self_calling_callback (void *parameter) {
   if (parameter) {
      basic_thread * thread = reinterpret_cast<basic_thread *>(parameter);
      thread->action_callback();
   }
   return 0; // The value returned only matters if someone starts calling GetExitCodeThread
             // to retrieve it.
}

basic_thread::basic_thread () {
   // Start thread.
   m_Handle = CreateThread(NULL,
                           0,
                           self_calling_callback,
                           (PVOID)this,
                           0,
                           &m_ThreadId );
   if( !IsHandleValid() )
      throw StartException("CreateThread() failed", GetLastError());

}

다른 팁

CreateThread는 2 인수를 원합니다 : 스레드로 실행하는 기능에 대한 포인터, 그리고 스레드에 주어진 dword 인수. spawnthread () 함수는 1 인수 (threadName) 만 있습니다. 너 생각한다 "I"때문에 2 개의 Args가 있지만 실제로 "ThreadName"유형의 정의의 일부입니다. (당신은 "I"를 제외 할 수 있습니다. 즉, "ThreadName"에 대한 인수를 지명 할 필요는 없습니다.)

어쨌든, 당신이 2 개의 인수가 필요하다는 것을 감안할 때, spawnthread를 재정의합니다.

   void spawnThread(void (*threadEntryPoint)(int), int argument)
   {
      CreateThread(0,0,
                   (LPTHREAD_START_ROUTINE)threadEntryPoint,
                   (LPVOID)argument,
                   0,0);
   }

내가하지 않았다는 것을 주목하십시오 이름 ThreadentRyPoint에 대한 인수; 컴파일러에 함수에 단일 INT 인수가 있어야한다고 말하는 것이 충분합니다.

그리고 그것을 호출하십시오 :

   spawnThread(printSome, 155);

어쨌든, 빠르고 더럽 으면, 이것은 당신이 원하는 것을 할 것입니다.

HTH.

레일리.

함수 포인터에서 매개 변수 정보를 전달할 수 없습니다. 별도로 통과해야합니다. 이것이 바로 CreateTheRad 기능이 원하는 것을 가리킬 수있는 무효* 매개 변수를 제공하는 이유입니다.

또한, 당신은해야합니다 CreateThread 대신 _beginthread를 사용하십시오 C ++ 응용 프로그램의 경우.

마지막으로, 스레드가 실행되기 전에 프로그램이 종료 될 가능성이 높습니다. 따라서 무기한 루프를 입력하거나 API 호출을 사용하여 스레드가 완료 될 때까지 기다려야합니다.

다음은 사용하는 작업 버전입니다 WaitforsingleObject 스레드가 완료 될 때까지 차단합니다.

#include <iostream>
#include <process.h>
#include <windows.h>

void
printSome(int i)
{
    std::cout << i << std::endl;
}

HANDLE
spawnThread(void (*threadName)(int), int i)
{
    return (HANDLE) _beginthread((void (*)(void*)) threadName, 0, (LPVOID) i);      
}

int
main(int argc, char *argv[])
{
    HANDLE threadHandle;

    threadHandle = spawnThread(printSome, 155);
    WaitForSingleObject(threadHandle, INFINITE);

    return 0;
}

다음은 동일한 상황을 처리하는 훨씬 더 C ++/객체 지향 방법입니다.

#include <iostream>
#include <process.h>
#include <windows.h>

class Thread {
    static void proxy(void *arg) { (*(reinterpret_cast<Thread *> (arg)))(); }
    HANDLE thread_;

public:
    virtual ~Thread() {}
    virtual void operator()() = 0;  
    void start() { thread_ = (HANDLE) _beginthread(Thread::proxy, 0, this);}    
    void waitForExit() { WaitForSingleObject(thread_, INFINITE); }
};

class Printer : public Thread {
    int i_;

public:
    Printer(int i) : i_(i) {}
    void operator()() { std::cout << i_ << std::endl; }
};

int
main(int argc, char *argv[])
{
    Printer p(155);

    p.start();
    p.waitForExit();

    return 0;
}

많은 사람들이 이미 여기에 언급했듯이 함수 포인터와 그 인수는 하나의 매개 변수로 호출되어야합니다.

당신의 라인

    spawnThread(printSome(155));

"DWIM 세계에서)는"인수가있는 별도의 스레드에서 printsome을 호출한다 "를 의미합니다. 그러나 C ++가 그것을 이해하는 방법은 아닙니다. C ++는 "Spawnthread의 매개 변수로 155에서 호출 된 Printsome의 결과를 통과합니다." 다시 말해, 일련의 단계는 다음과 같습니다.

  • 논쟁으로 155로 prinotsome을 호출하십시오. 임시 메모리에 저장하십시오.
  • 임시 메모리의 내용을 인수로 SpawnThread를 호출하십시오.

당신이 실제로 의미하는 바를 수행하려면 C ++를 유머하고 기능과 분리해야합니다. 그것을하는 방법은 이미 다른 답변으로 설명되어 있습니다. 그것의 부족은 다음과 같습니다.

callonotherthreadwithargument (함수, 정수);

여기서 어떻게하는지 읽을 수 있습니다. http://www.newty.de/fpt/fpt.html

2.6 인수로 함수 포인터를 전달하는 방법은 무엇입니까?

함수의 호출 인수로 함수 포인터를 전달할 수 있습니다. 예를 들어 포인터를 콜백 함수로 전달하려는 경우이 작업이 필요합니다. 다음 코드는 int를 반환하고 플로트와 두 숯을 가져 오는 함수로 포인터를 전달하는 방법을 보여줍니다.

//------------------------------------------------------------------------------------
// 2.6 How to Pass a Function Pointer

// <pt2Func> is a pointer to a function which returns an int and takes a float and two char
void PassPtr(int (*pt2Func)(float, char, char))
{
   int result = (*pt2Func)(12, 'a', 'b');     // call using function pointer
   cout << result << endl;
}

// execute example code - 'DoIt' is a suitable function like defined above in 2.1-4
void Pass_A_Function_Pointer()
{
   cout << endl << "Executing 'Pass_A_Function_Pointer'" << endl;
   PassPtr(&DoIt);
}
라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top