从LPVOID转换为结构 - C

Jam*_*ing 2 c winapi

我正在编写一个简单的控制台应用程序,它允许我从通过我提供的参数传递的一组参数中创建许多线程.

DWORD WINAPI ThreadFunc(LPVOID threadData)
{
}
Run Code Online (Sandbox Code Playgroud)

我将它们打包成一个结构并将它们作为参数传递给CreateThread方法,并尝试通过将它们从LPVOID转换为与我的结构相同的类型来解压缩它们.

我不知道如何在完成它之后将它转换为结构,所以我可以在方法本身中使用它,我尝试了各种组合(示例attatched)但它不会编译.

结构:

#define numThreads 1

struct Data
{
    int threads;
    int delay;
    int messages;
};
Run Code Online (Sandbox Code Playgroud)

致电方法:

HANDLE hThread;
    DWORD threadId;
    struct Data *tData;

    tData->threads = numThreads;
    tData->messages = 3;
    tData->delay = 1000;


    // Create child thread
    hThread = CreateThread(
                            NULL,       // lpThreadAttributes (default)
                            0,          // dwStackSize (default)
                            ThreadFunc, // lpStartAddress
                            &tData,     // lpParameter
                            0,          // dwCreationFlags
                            &threadId   // lpThreadId (returned by function)
                           );
Run Code Online (Sandbox Code Playgroud)

我的尝试:

DWORD WINAPI ThreadFunc(LPVOID threadData)
    {
        struct Data tData = (struct Data)threadData;

        int msg;

        for(msg = 0; msg<5; msg++)
        {
            printf("Message %d from child\n", msg);
        }
        return 0;
}
Run Code Online (Sandbox Code Playgroud)

编译错误:

错误C2440:'type cast':无法从'LPVOID'转换为'数据'

正如您所看到的,我已经实现了一种循环遍历大量消息的方法,我正在尝试使事情略微更高级并添加一些其他功能.

Sco*_*ith 9

好的,对于初学者来说,这将会爆发:

struct Data *tData;

tData->threads = numThreads;
tData->messages = 3;
tData->delay = 1000;
Run Code Online (Sandbox Code Playgroud)

...因为你已经创建了一个类型为'指向结构的指针'的变量,但你没有初始化指针指向任何东西.tData是未初始化的,所以你写的是一个狂野的指针.

你可能想要这样的东西:

// Allocate memory for the struct on the heap
struct Data *tData = malloc( sizeof(struct Data) );

// Initialize _all_ fields of the struct (malloc won't zero fill)
tData->threads = numThreads;
tData->messages = 3;
tData->delay = 1000;
Run Code Online (Sandbox Code Playgroud)

其次,您传递的是(变量所在的内存中的位置)的地址,而不是内存中指向的位置:tDatatDatatData

// Create child thread
hThread = CreateThread( ...,
                        &tData, // OOPS - ADDRESS OF THE POINTER VARIABLE ITSELF!
                        ... );
Run Code Online (Sandbox Code Playgroud)

您可能希望传递指针的值(它指向的结构的地址):

// Create child thread
hThread = CreateThread( ...,
                        tData,  // Value of the pointer
                        ... );
Run Code Online (Sandbox Code Playgroud)

当您在回调函数中收到结构的地址时,将其强制转换回原始的指针结构类型,取消引用并享受:

DWORD WINAPI ThreadFunc(LPVOID threadData)
{
    struct Data *tData = (struct Data *)threadData;

    int numMessages = tData->messages;
    // ...
}
Run Code Online (Sandbox Code Playgroud)