473,796 Members | 2,473 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

How to call static DWORD WINAPI ThreadFunc(LPVO ID pvParam)

52 New Member
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(LPVO ID 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 12655
horace1
1,510 Recognized Expert Top Contributor
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 Recognized Expert Top Contributor
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
ppuniversal
52 New Member
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 Recognized Expert Top Contributor
try declaring runThread static
Expand|Select|Wrap|Line Numbers
  1. static DWORD WINAPI GridServer :: runThread(LPVOID Parameter)
  2.  
Feb 18 '07 #5
ppuniversal
52 New Member
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 Recognized Expert Top Contributor
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
2163
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 I now want to translate the wrapper to C#. I can find my around C# in a (pardon the pun) basic fashion. I am looking to translate the Main routine below.
3
2108
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 header looks like: #ifdef TESTDLL_EXPORTS #define TESTDLL_API __declspec(dllexport)
1
6722
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 NumBytesToRead, DWORD *NumBytesReturned) Where the following arguments are described as
7
10603
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 the philosophy behind this type. What I don't get is why doesn't a person pass in a pointer to the datatype they need, instead of LPVOID. Can you provide a simple example to demonstrate how the LPVOID, was/is
1
2379
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 , name_of_C#function_parms_to_be_handled) First off I want to know if my idea is possible, but a simple example would be nice. :)
13
2215
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, etc. However not really knowing c++ I would rather use C#. Could you point me to documentation/information on how to use this c++ information to properly construct my C# routine to connect properly?
4
9099
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
5261
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 failing on the call to FormatMessage. Cannot marshal 'parameter #7': Pointers cannot reference marshaled structures. Use ByRef instead. how do I pass the argument ByRef and why is managed code involved in this api call? FormatMessage is an...
4
4241
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 an abstract class with one pure virual function. Now, all of the classes derived from the base abstract class have a ThreadProc function, for the job that the worker threads do. They must have it because of the nature of the abstract class. So, in...
0
9528
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 effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10456
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, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10174
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10012
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
1
7548
isladogs
by: isladogs | last post by:
The next Access Europe User Group meeting will be on Wednesday 1 May 2024 starting at 18:00 UK time (6PM UTC+1) and finishing by 19:30 (7.30PM). In this session, we are pleased to welcome a new presenter, Adolph Dupré who will be discussing some powerful techniques for using class modules. He will explain when you may want to use classes instead of User Defined Types (UDT). For example, to manage the data in unbound forms. Adolph will...
0
5442
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5575
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
2
3731
muto222
by: muto222 | last post by:
How can i add a mobile payment intergratation into php mysql website.
3
2926
bsmnconsultancy
by: bsmnconsultancy | last post by:
In today's digital era, a well-designed website is crucial for businesses looking to succeed. Whether you're a small business owner or a large corporation in Toronto, having a strong online presence can significantly impact your brand's success. BSMN Consultancy, a leader in Website Development in Toronto offers valuable insights into creating effective websites that not only look great but also perform exceptionally well. In this comprehensive...

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.