0

I'm not sure what the correct syntax is for this because it involves the winapi which i'm not familiar with. For example, i didnt know it won't let me xhangethe predefined thread function parameters from processClient(LPVOID) to processClient(LPVOID&).

I need to pass the "params" object by reference(just so theres no problems for now, even though im not going to change values in it) to the thread function "processClient()".

... struct(the object) declaration
struct ClientParams{

    ClientParams::ClientParams():sock(INVALID_SOCKET), i(NULL){};

public:
    SOCKET sock;
    int i;
};

... in processClient(LPVOID lpParam){
    SOCKET ClientSocket=(SOCKET)*lpParam->sock; ?? doesnt work
    int i=*lpParam->i; ?? doesn't work
}
... in main{
ClientParams *params = new ClientParams();
params->i=some_value;
params->sock=ClientSocket;
CreateThread(
            NULL,                       // don't inherit handle
            0,                          // use default size for the executable
            processClient,
            (LPVOID)params,             // thread data
            0,                          // run right away
            &i );
}
shawn a
  • 689
  • 2
  • 11
  • 18
  • I suggest using `std::thread` instead for ease, but it's already a pointer, so just pass in a pointer to what you need and convert it to the same pointer inside. – chris Dec 24 '13 at 02:07
  • `SOCKET ClientSocket = ((ClientParams*)lpParam)->sock;` - basic C++. Maybe a multithreaded networking application is not the best fit for a first project. – IInspectable Dec 24 '13 at 02:10
  • @IInspectable, You're dereferencing a void pointer. Anyway, you mean C. C++ really does have better ways than void pointers. – chris Dec 24 '13 at 02:11
  • @chris You cannot use C++ when calling a C API... – IInspectable Dec 24 '13 at 02:14
  • @IInspectable, I mean the method of using void pointers as data parameters, though. It originated from C, and I cannot think of a time when I'd rather do that than use a safer and easier C++ method of accomplishing the same thing. Thus, I compare this to learning C strings instead of `std::string`, or manual memory management instead of RAII-based utilities. One is obviously a lot more C-like and C++ programmers don't generally do things that way. In any case, the most C++ way for this specific task is the standard threading library, which also does the data parameters in a better way. – chris Dec 24 '13 at 02:16
  • @chris This question is tagged [winapi]. The most C++ way for this specific task is to call a C interface. And since this question is tagged [winapi] the standard threading library is certainly a **lot** less capable than the native synchronization primitives. – IInspectable Dec 24 '13 at 02:28
  • @IInspectable, A lot less capable? A simple line to create the object and pass in the data, whatever functions it has, and then you can get the `HANDLE` for it any time you need to do anything it doesn't offer (although Boost's has `interrupt` and whatnot). It's a lot simpler on the outside and being able to get the handle allows for anything possible with winapi calls to happen as well. – chris Dec 24 '13 at 02:31
  • @IInspectable, Anyway, it certainly is possible to use C++ to some extent when dealing with a C API. The thread handle is one example, but also consider using a vector, passing the direct memory instead of the vector itself, and continuing with what you were using it for before. The question is also tagged C++, so I don't see why standard C++ automatically doesn't apply. For all I know, the OP would love `std::thread`, but never knew it existed. – chris Dec 24 '13 at 02:35
  • CreateThread shouldn't be used as it leaks, also you are leaking the handle it returns, and not checking if creating the thread actually worked – paulm Dec 24 '13 at 09:06
  • @paulm `CreateThread` does not leak. What makes you think it would? And what would you propose instead? And how does this proposed superior alternative - which eventually calls `CreateThread` itself - magically remove the leakage from an API it does not control? – IInspectable Dec 24 '13 at 10:50
  • It causes a leak if you're using the CRT - which most people do. http://stackoverflow.com/questions/331536/windows-threading-beginthread-vs-beginthreadex-vs-createthread-c – paulm Dec 24 '13 at 11:26
  • @paulm `_beginthreadex` calls `CreateThread`. So if `CreateThread` causes a leak, then so does `_beginthreadex`. Neither is true. `_beginthread[ex]` is required to set up per-thread state, like `errno`, locale, floating point environment, etc.. Failure to call `_beginthread[ex]` does not cause a leak. It simply invokes undefined behavior, when calling one of the CRT functions that require per-thread state. – IInspectable Dec 24 '13 at 12:25
  • CreateThread() won't leak, but there will still be a memory leak: http://support.microsoft.com/kb/104641/en-us – paulm Dec 24 '13 at 12:47
  • @paulm So in other words: The **CRT** leaks memory when used on a thread that wasn't prepared to run code from the CRT. This doesn't come as much of a surprise. Calling `CreateThread` is perfectly safe, and sound, and never leaks. – IInspectable Dec 24 '13 at 12:52
  • Since he *is* using the CRT he has a memory leak, therefore in any normal win32 app that uses the CRT I wouldn't say its "safe and sound" since its usage will cause a memory leak. – paulm Dec 24 '13 at 12:58
  • @paulm Kudos for reading the OP's mind. I do not see the definition of `processClient` so I cannot possibly know whether or not he is running CRT code on the thread. The point is: `CreateThread` does not leak and is not inherently unsafe. If you want to use the CRT however, make sure to play by the rules. – IInspectable Dec 24 '13 at 13:10
  • He is using operator new, so I don't need to read his mind, operator new is provided by the CRT. – paulm Dec 24 '13 at 13:14
  • @paulm You misinterpret the rules. The rules are that you must initialize the CRT on a thread, **if that thread uses the CRT**. `operator new` is not called on the thread in question; the call to `CreateThread` can be perfectly safe. With the information provided we don't know for sure, one way or another. Aside: `operator new` is not provided by the CRT. However, it calls `malloc` and can throw exceptions - both of these are implemented in the CRT. – IInspectable Dec 24 '13 at 13:25
  • What provides operator new? If I build apps without a CRT I have to define my own, usually calling HeapAlloc(). – paulm Dec 24 '13 at 13:43
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/43836/discussion-between-iinspectable-and-paulm) – IInspectable Dec 24 '13 at 13:51

2 Answers2

2

SOCKET ClientSocket=(SOCKET)*lpParam->sock; ?? doesnt work

lpParam has the same value it did when you passed it, in main, where it was 'params', of type 'ClientParams*', so you don't have any business dereferencing it with '*'. The rest of it is just a precedence problem. It should be

SOCKET ClientSocket=((ClientParams*)lpParam)->sock;
user207421
  • 289,834
  • 37
  • 266
  • 440
0

Access structure members must through the structure.

SOCKET ClientSocket=((ClientParams*)lpParam)->sock;
Lange
  • 1
  • 1