473,395 Members | 1,502 Online
Bytes | Software Development & Data Engineering Community
Post Job

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 473,395 software developers and data experts.

How to call static DWORD WINAPI ThreadFunc(LPVOID pvParam)

I am facing a problem:

I have say 3 files :

ABC.h ----- this file has the function prototypes
ABC.cpp ------ the definitions of the functions
ABC_Test.cpp ------- the file with main() which calls the functions using ABC's object say "ob".


Now I want to make a function say "startNewThread()" inside ABC.cpp and its prototype in ABC.h, then where should I define

static DWORD WINAPI ThreadFunc(LPVOID pvParam);

function. Inside ABC_Test.cpp or inside ABC.cpp

Also Iwill call the createThread() of Win API inside startNewThread() and pass the ThreadFunc as one of its parameters. If this is possible, then its OK. But if I have to call some function of mine say

void ABC :: printXYZ() inside ThreadFunc , then how can I do this. I do not have my object say ABC ob; i.e. "ob" inside my ThreadFunc.

Please reply, if possible with a EXAMPLE code

Pawan
Feb 17 '07 #1
6 12613
horace1
1,510 Expert 1GB
not sure what the probelm is but you can call functions defined in your program from inside the threaded function. e.g.
Expand|Select|Wrap|Line Numbers
  1. #include <iostream>
  2. #include <windows.h>
  3. #include <process.h>
  4. using namespace std;
  5.  
  6. // function to print an int
  7. void myFunction(int i)
  8. {
  9.      cout << "This is prcosses number: " << i << "\n";
  10. }
  11.  
  12. // the thread function
  13. DWORD WINAPI ThreadProc(void *number)
  14. {    
  15.      int myNumber = *(int*)number;
  16.      myFunction(myNumber);
  17.      _endthread();
  18. }
  19.  
  20. // test from to call the thread function 10 times
  21. int main(int argc, char *argv[])
  22. {
  23.     int tempNum[10];
  24.     for( int i = 0; i <= 9; i++){
  25.          tempNum[i] = i;
  26.          HANDLE  handle = (HANDLE)CreateThread( NULL, 0, ThreadProc, (void*)&tempNum[i],0, NULL); // create thread
  27.         }  
  28.     system("PAUSE");
  29.     return 0;
  30. }
  31.  
Just be careful about accessing shared data structures etc
Feb 17 '07 #2
AdrianH
1,251 Expert 1GB
Expand|Select|Wrap|Line Numbers
  1.          HANDLE  handle = (HANDLE)CreateThread( NULL, 0, ThreadProc, (void*)&tempNum[i],0, NULL); // create thread
  2.  
What is important here is that you can pass a pointer. Oh, and that ThreadProc doesn't need to be called ThreadProc.

You can pass a pointer to an object if you like. Say you have a function DWORD fooThread(void * pObj), and an object fooObj of type foo. Then this becomes
Expand|Select|Wrap|Line Numbers
  1.          HANDLE  handle = (HANDLE)CreateThread(NULL, 0, fooThread, &fooObj, 0, NULL); // create thread
  2.  
and you function would be like so:
Expand|Select|Wrap|Line Numbers
  1. staic DWORD WINAPI fooThread(void* pObj)
  2. {
  3.   foo& rObj = *static_cast<foo*>(pObj);
  4.   rObj.memberFn();
  5.   return 0;
  6. }
  7.  
Hope this helps.


Adrian

Just be careful about accessing shared data structures etc
Yeah, what he said.
Feb 17 '07 #3
Here's everything in more detail :

The 3 file are :
1) GridServer.h containing function prototypes
Expand|Select|Wrap|Line Numbers
  1. DWORD WINAPI runThread(LPVOID Parameter);
  2. void startNewThread(SOCKET c_socket);
2) GridServer.cpp ---- the .cpp file with function definitions

Expand|Select|Wrap|Line Numbers
  1. DWORD WINAPI GridServer :: runThread(LPVOID Parameter)
  2. {
  3.     //Get the information about client entity
  4.     SOCKET clientSocket = (SOCKET)Parameter;
  5.  
  6.     printf( "\n New Client Connected.\n");
  7.     cout.flush();
  8.  
  9.     int bytesRecv = SOCKET_ERROR;
  10.     char  *recvbuf;
  11.     recvbuf = new char[1];
  12.  
  13.     int ch ;
  14.     bytesRecv = recv( clientSocket, recvbuf, 1, 0 );
  15.     cout.flush();
  16.  
  17.     printf( "\n Bytes Received: %ld", bytesRecv );
  18.     printf("\n Data Received = %c", recvbuf[0]);
  19.  
  20.     ch = atoi(recvbuf);
  21.  
  22.  
  23.     switch(ch)
  24.     {
  25.         case 1    :    getFile(clientSocket);
  26.                     break;
  27.         case 2  :    createAccount(clientSocket,TABLE_OF_INTEREST);
  28.                     break;
  29.         default    :    printf("\n Invalid option sent from client.");
  30.                     break;
  31.     }
  32.  
  33.     return 0;
  34. }
  35.  
  36. /******************/
  37. void GridServer :: startNewThread(SOCKET c_socket)
  38. {
  39.  
  40.     HANDLE hThread;    //Handle to thread
  41.     DWORD ThreadId;    //used to store the thread id
  42.  
  43.  
  44.     hThread = CreateThread(    NULL,
  45.                             0,
  46.                             &GridServer::runThread,
  47.                             (LPVOID)c_socket,
  48.                             0,
  49.                             &ThreadId);
  50.  
  51.     //printf("\n After CreateThread()");
  52.     return;
  53.  
  54. }
  55.  

and
3) GridServer_Test.cpp ---- the .cpp with main()

it makes a GridServer object named : "ob" and calls
Expand|Select|Wrap|Line Numbers
  1. ob.startNewThread(acceptSocket);
here acceptSocket is a variable of type SOCKET.

now the problems are :

when I compile the code, I get the following error :

Expand|Select|Wrap|Line Numbers
  1. g:\smartsafe\gridserver\gridserver.cpp(207) : error C2664: 'CreateThread' : cannot convert parameter 3 from 'DWORD (__stdcall GridServer::* )(LPVOID)' to 'LPTHREAD_START_ROUTINE'
  2.         There is no context in which this conversion is possible
  3.  
What should I do?
What I require are :
1) calling the runThread() function properly from startNewThread() using CreateThread().
2)Also if you can see that I am calling getFile() and createAccount() from inside the runThread() I want this to be called, with respect to the object which called startNewThread().

I think I have tried to make my code clear this time.
Please Reply, if more information is required, I will reply
Pawan
Feb 18 '07 #4
horace1
1,510 Expert 1GB
try declaring runThread static
Expand|Select|Wrap|Line Numbers
  1. static DWORD WINAPI GridServer :: runThread(LPVOID Parameter)
  2.  
Feb 18 '07 #5
Can you be more elaborate? What changes will be there if I make it static, because someone else told me the other way, I was using static previously in its declaration and definition.

Please reply
Pawan
Feb 18 '07 #6
AdrianH
1,251 Expert 1GB
Can you be more elaborate? What changes will be there if I make it static, because someone else told me the other way, I was using static previously in its declaration and definition.

Please reply
Pawan
Expand|Select|Wrap|Line Numbers
  1. DWORD WINAPI GridServer::runThread(LPVOID Parameter)
  2.  
I'm assuming that GridServer is a class.

Now, you cannot pass a member function to CreateThread(). This is because a member function has an implicit pointer passed, namely the this pointer. There are also other things that may be happening 'under the hood' that may not be standard under all C++ implementations.

By declaring the member static, it gets rid of the implicit this pointer and should degrade into a standard C function that has access to objects of the class it was declared in.

But now you’ve lost the this pointer. You can no longer access the regular (non-static) member functions in the class because you don’t have an object for the member functions to act upon. So to your thread, you must pass a pointer to the object.

So now you’ve got a small problem, you need to pass a socket and the object. You can do this in two ways:
  1. Store the socket in the object prior to spawning the thread.
  2. Or create a structure that will hold the socket and a pointer to the object. Create this structure on the heap with the new operator and fill it with the socket and pointer to the object. Pass this structure to the new thread.
On the other side (inside your runThread() function), you will have to recast the pointer to match what you are passing to the CreateThread() function).


Hope this helps.


Adrian
Feb 19 '07 #7

Sign in to post your reply or Sign up for a free account.

Similar topics

9
by: bclegg | last post by:
Hi, I am a VB.net programmer who has to make use of a 3rd party Borland C++ dll. We have a successful VC++ wrapper that presents a number of functions that can be declared and called in VB.net ...
3
by: Tony Liu | last post by:
Dear All: I create a very simple DLL by using EVC to test the problem. (The platform I am working for those program is WinCE.NET) ******************************************************* The...
1
by: LongBow | last post by:
Hello, I am attempting to create an application that uses an existing driver interface API using C#. I have an API that looks like F32x_Read( HANDLE Handle, LPVOID Buffer, DWORD...
7
by: Russell Mangel | last post by:
I have been doing some C++ Interop using the new VS2005 (June Beta). I am exposing these methods to .NET clients. I ran into some WinAPI methods which use LPVOID types, and I don't understand...
1
by: Mads Westen | last post by:
Hi, I want to create a "dynamic" unmanaged VC++ wrapper that can call any C# DLL. I'm thinking that I call the the wrapper from another program like this: dllcall(name_of_wrapper_function ,...
13
by: Raj Wall | last post by:
Hi, I have an application that allows functionality extension by third party DLL's. All the specs for building these DLL's are targeted to c++, with demo.h files containing "extern" statements,...
4
by: ppuniversal | last post by:
Hello, I am making a thread program, in which i call : hThread = CreateThread( NULL, 0, (LPTHREAD_START_ROUTINE)(this->runThread), this, 0, &ThreadId);
4
by: Steve Richter | last post by:
I have a C++ forms project that I am adding some unmanaged code to. I have a member function of the Form1 class that returns a String^ holding the text of the last win32 error. The code is...
4
emibt08
by: emibt08 | last post by:
Hi. I know the title looks a little bit silly and that we can not have pure virtual static functions. But i've been wondering what approach to take to make the abstraction. This is the case: I have...
0
by: Charles Arthur | last post by:
How do i turn on java script on a villaon, callus and itel keypad mobile phone
0
by: emmanuelkatto | last post by:
Hi All, I am Emmanuel katto from Uganda. I want to ask what challenges you've faced while migrating a website to cloud. Please let me know. Thanks! Emmanuel
0
BarryA
by: BarryA | last post by:
What are the essential steps and strategies outlined in the Data Structures and Algorithms (DSA) roadmap for aspiring data scientists? How can individuals effectively utilize this roadmap to progress...
1
by: nemocccc | last post by:
hello, everyone, I want to develop a software for my android phone for daily needs, any suggestions?
1
by: Sonnysonu | last post by:
This is the data of csv file 1 2 3 1 2 3 1 2 3 1 2 3 2 3 2 3 3 the lengths should be different i have to store the data by column-wise with in the specific length. suppose the i have to...
0
by: Hystou | last post by:
There are some requirements for setting up RAID: 1. The motherboard and BIOS support RAID configuration. 2. The motherboard has 2 or more available SATA protocol SSD/HDD slots (including MSATA, M.2...
0
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can...
0
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers,...
0
jinu1996
by: jinu1996 | last post by:
In today's digital age, having a compelling online presence is paramount for businesses aiming to thrive in a competitive landscape. At the heart of this digital strategy lies an intricately woven...

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.