从 LPVOID 转换为结构体 - C

标签 c winapi

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

DWORD WINAPI ThreadFunc(LPVOID threadData)
{
}

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

我不确定如何在通过后将其转换为结构,以便我可以在方法本身中使用它,我尝试了各种组合(附上示例)但它不会编译。

结构:
#define numThreads 1

struct Data
{
    int threads;
    int delay;
    int messages;
};

调用方法:
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)
                           );

我的尝试:
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;
}

编译器错误:

错误 C2440:“类型转换”:无法从“LPVOID”转换为“数据”

正如您所看到的,我已经实现了一种循环遍历许多消息的方法,我正在尝试使事情变得更高级并添加一些进一步的功能。

最佳答案

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

struct Data *tData;

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

...因为您已经创建了一个“指向结构的指针”类型的变量,但是您还没有将指针初始化为指向任何东西。 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;

其次,您传递的地址是 tData (tData 变量在内存中的位置),而不是 tData 在内存中的位置指向:
// Create child thread
hThread = CreateThread( ...,
                        &tData, // OOPS - ADDRESS OF THE POINTER VARIABLE ITSELF!
                        ... );

您可能想要传递指针的值(它指向的结构的地址):
// Create child thread
hThread = CreateThread( ...,
                        tData,  // Value of the pointer
                        ... );

当您在回调函数中收到结构体的地址时,将其转换回原始的结构体指针类型,取消引用并享受:
DWORD WINAPI ThreadFunc(LPVOID threadData)
{
    struct Data *tData = (struct Data *)threadData;

    int numMessages = tData->messages;
    // ...
}

关于从 LPVOID 转换为结构体 - C,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2427620/

相关文章:

C:使用指针修改数组中的 const 数据

在 C 中将负 int 转换为更大的无符号 int

c - 应用程序结果受到另一个正在运行的应用程序的影响

c++ - 在二进制数据文件的头部放什么

c - c中的开关和大小写如何匹配?

java - 是否有与 unputc 等效的 Java?

winapi - 如何在禁用组框时禁用组框文本?

visual-studio-2010 - Visual Studio 2012 中的 DEF 文件语法错误

c++ - GetOpenFileName 函数未打开对话框

windows - 检查文件写入权限时,FILE_ATTRIBUTE_READONLY 与使用访问控制列表之间的关系是什么?