Thread: Pass parameter to a thread

  1. #1
    Registered User
    Join Date
    Mar 2011
    Posts
    216

    Pass parameter to a thread

    Hi, I'm trying to pass a parameter to a thread, by using CreateThread(). Unfortunately, you have to pass LPVOID or void* as it's only parameter.

    I'm trying to pass a structure to it, which should then be passed to another function to handle the data. I would make the structure a global, but it must be defined in a separate function I have.

    I read somewhere that
    Code:
    if (sizeof(DATA) <= sizeof(void *))
    then you can just cast it as a void*, but I don't know how to do that.

    The structure is made like so

    Header
    Code:
    struct Download
    {
           char name[56];
           char outName[16];
    };
    Main Prog
    Code:
    int num_files;
    ...
    num_files = x;
    ...
    struct Download file[num_files];
    Thanks for the help!

  2. #2
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    The reason the single argument is a pointer, is so you can use it to... point at something. So create your parameter structure and pass a pointer to it.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  3. #3
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    So like
    Code:
    struct *Download file
    ...
    DWORD WINAPI function(struct *Download file)
    I don't fully understand what you mean?

  4. #4
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    void* is used in C as a 'generic pointer'. It effectively means that you can pass a pointer to whatever you want, it won't matter as long as the receiving party interprets the data correctly.

    So brewbuck's suggestion is really as simple as it sounds, just pass in the pointer.

  5. #5
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    I keep getting this error when I go compile
    Code:
    DWORD WINAPI CheckUpdate(void* Download file[]);
    expected `,' or `...' before "file"
    I don't know what I am doing wrong.

  6. #6
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    Ok, so this has seemed to work, but unfortunately, not everything is perfect. In the function, I need to access variables from the structure, but it's a pointer now. How do I do that, because this isn't working.
    Code:
    void DownloadUpdates(void* file[])
    {
         int j;
         
         for(j = 0; j < num_files; j++)
         {
               SendMessage(hwndpb, PBM_SETPOS, 0, 0);
               //DownloadFile(file[j].name, file[j].outName); for reg struct
               DownloadFile((*file)[j].name, (*file)[j].outName);
         }
    }
    Where 'file' is the structure.

  7. #7
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    Ok, so I'm sure I've passed the structure as a pointer to the function, but here is the problem. It requires a void pointer (because I'm launching it in it's own thread) but the compiler spits out this error.
    Code:
    invalid conversion from `DWORD (*)(Download**)' to `DWORD (*)(void*)'
    And here is the code I'm working with (the function launched w/ CreateThread ~ this needs to have a void * as the paremeter)
    Code:
    DWORD WINAPI CheckForUpdate(struct Download *file[])
    {
         GetProgVersion();
         
         num_files = GetUpdate();
          
         SendMessage(hwndpb, PBM_SETRANGE, 0, MAKELPARAM(0, 200 ));
                
         if(version.major > curVer.major || version.minor > curVer.minor || version.build > curVer.build)
         {
                 int ret = MessageBox(hWnd, "An update is available to download.  Would you like to download it?", "Update Available", MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1);
                          
                 if(ret == IDNO)
                         return 2;
                          
                 DownloadUpdates(file);
                 
                 return 0;
         }
         else
                 MessageBox(hWnd, "No updates are available to download.", "No Updates Available", MB_OK | MB_ICONINFORMATION);
    
         return 1;
    }
    So how do I make it void *?

  8. #8
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    Ok I understand what your problem is now.

    The parameter to your function that is being executed in the new thread should simply be 'void* ptr' or whatever you want to call it. In your code you then cast this to the appropriate variable type (struct Download* or something) so that you can properly access it.

  9. #9
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    Ok, so when I replace
    Code:
    DWORD WINAPI CheckForUpdate(struct Download *file[])
    with
    Code:
    DWORD WINAPI CheckForUpdate(void *file[])
    I get this error.
    Code:
    invalid conversion from `DWORD (*)(void**)' to `DWORD (*)(void*)'

  10. #10
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    [] means variable length array, so you're essentially saying that the parameter is void ** (as the error says).

    Get rid of the [], it's not important that your parameter is only void*, what is important is what you cast the parameter to to access it.

  11. #11
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    When I remove the [], I get this error in my DownloadUpdates function. (which I call in the CheckForUpdate function ~ which is the new thread)

    Code:
    `void*' is not a pointer-to-object type
    Function which is called in CheckForUpdate (the thread function)
    Code:
    void DownloadUpdates(void *file)
    {
         int j;
         
         for(j = 0; j < num_files; j++)
         {
               SendMessage(hwndpb, PBM_SETPOS, 0, 0);
               //DownloadFile(file[j].name, file[j].outName); for reg struct
               DownloadFile((*file)[j].name, (*file)[j].outName); // error on this line
         }
    }
    I need to be able to cycle through the contents of the file structure (however many items there will be) and execute on the appropriate ones.

  12. #12
    Registered User
    Join Date
    Jan 2009
    Location
    Australia
    Posts
    375
    When you use a void pointer the compiler no longer knows what the original type of the variable was. You can't just expect the compiler to know that your 'file' variable is actually some sort of structure when you've made it a void variable.

    This is why we cast the void pointer to whatever it is supposed to be, so that it can be properly accessed:

    Code:
    int DoSomething( void *var1 )
    {
            int *var1cast = (int*)var1;
            
            return *var1cast + 1;
    }
    
    int main( void )
    {
            int num;
    
            num = 10;
    
            printf( "%d\n", DoSomething( (void*)&num ) );
    
            return 0;
    }
    Some of this may be wrong. It's been a while since I've even used void pointers and it's not like I ever used them very much. Note that this code only demonstrates the syntactic usage of void pointers. It does not actually show a situation in which void pointers would be used.

  13. #13
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    So I've ran through the code, and from my knowledge, it should all make sense to the compiler, yet I have another pair of errors.

    Code:
    void DownloadUpdates(void *file)
    {
         int j;
         
         for(j = 0; j < num_files; j++)
         {
               SendMessage(hwndpb, PBM_SETPOS, 0, 0);
               DownloadFile((struct*)file[j].name, (struct*)file[j].outName); //ERRORS ARE HERE
               //DownloadFile((*file)[j].name, (*file)[j].outName);
         }
    }
    
    DWORD WINAPI CheckForUpdate(void *file)
    {
         GetProgVersion();
         
         num_files = GetUpdate();
          
         SendMessage(hwndpb, PBM_SETRANGE, 0, MAKELPARAM(0, 200 ));
                
         if(version.major > curVer.major || version.minor > curVer.minor || version.build > curVer.build)
         {
                 int ret = MessageBox(hWnd, "An update is available to download.  Would you like to download it?", "Update Available", MB_YESNO | MB_ICONQUESTION | MB_DEFBUTTON1);
                          
                 if(ret == IDNO)
                         return 2;
                          
                 DownloadUpdates((void*)file);
                 
                 return 0;
         }
         else
                 MessageBox(hWnd, "No updates are available to download.", "No Updates Available", MB_OK | MB_ICONINFORMATION);
    
         return 1;
    }
    Errors
    Code:
    1. expected primary-expression before "struct" 
    2. expected `)' before "struct"
    These 2 errors both occur here:
    Code:
    DownloadFile((struct*)file[j].name, (struct*)file[j].outName);
    Am I casting the file structure correctly?

  14. #14
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    Have you thought about brushing up on your basics? In the three threads of yours that I've seen, you've had difficulty implementing answers you've being receiving unless they come with copy & pasteable code, and then you've sometimes pasted it in the wrong place.

    You'll be much more efficient if you take a couple of days/weeks/book chapters to muddle through the things which cause these common compile errors, how you can overcome them, how pointers and the type system works, when and why you need to cast, etc. You do have to walk before you run, and for a multithreaded anything, much less something complex like a game, you may be attempting to fly.

    NB, your update check isn't foolproof. If curVer is 2.1.0 and version is 1.4.0, it''ll say there's an upgrade.

  15. #15
    Registered User
    Join Date
    Mar 2011
    Posts
    216
    Can you explain what's wrong with my code, and what needs to change for it work?

    And if curVer is 2.1.0, it's highly likely that the update version will be 2.1.0 as well.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Replies: 2
    Last Post: 11-27-2011, 07:40 PM
  2. Replies: 9
    Last Post: 10-19-2009, 04:46 PM
  3. How pass NULL for a parameter in a function?
    By 6tr6tr in forum C++ Programming
    Replies: 2
    Last Post: 04-02-2008, 01:29 PM
  4. how would i pass on a vector pointer parameter
    By bugmenot in forum C++ Programming
    Replies: 5
    Last Post: 12-16-2005, 02:51 AM
  5. Parameter pass
    By Gades in forum C Programming
    Replies: 28
    Last Post: 11-20-2001, 02:08 PM

Tags for this Thread