我正在编写一个简单的控制台应用程序,它允许我从通过我提供的参数传递的一组参数中创建一些线程。
DWORD WINAPI ThreadFunc(LPVOID threadData)
{
}
我将它们打包到一个结构中,并将它们作为参数传递给CreateThread方法,并尝试通过将它们从LPVOID转换为与我的结构相同的类型来解压缩它们。
我不知道如何在完成它之后将它强制转换为结构,所以我可以在方法本身中使用它,我尝试了各种组合(例如attatched)但它不会编译。
STRUCT:
#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:'type cast':无法从'LPVOID'转换为'数据'
正如您所看到的,我已经实现了一种循环遍历大量消息的方法,我正在尝试使事情略微更高级并添加一些其他功能。
答案 0 :(得分:9)
好的,对于初学者来说,这将会爆发:
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
变量所在的位置),而不是内存中{{1}的位置} 指向:
tData
您可能希望传递指针的值(它指向的结构的地址):
// Create child thread
hThread = CreateThread( ...,
&tData, // OOPS - ADDRESS OF THE POINTER VARIABLE ITSELF!
... );
当你在回调函数中收到struct的地址时,将它强制转换回原始的指针结构类型,取消引用并享受:
// Create child thread
hThread = CreateThread( ...,
tData, // Value of the pointer
... );
答案 1 :(得分:4)
首先,您只创建一个指向结构而不是结构本身的指针,然后使用未初始化的指针。
struct Data *tData;
tData->threads = numThreads;
tData->messages = 3;
tData->delay = 1000;
您需要创建一个结构。如果创建线程的函数将在线程完成之前退出,那么您需要动态创建它。 e.g。
struct Data *tData = malloc(sizeof *tData);
你应该确保在其他地方的适当位置释放结构,如果它没有在其他地方使用,可能在线程函数的末尾。
然后尝试将LPVOID
参数强制转换为结构,其中您传递的是指向结构的指针。该参数不会大到足以按值传递整个结构。您可能只希望传入指向结构的指针(传入tData
而不是&tData
传递给CreateThread
,然后您可以从LPVOID
初始化为指向结构的指针。(因为这是C,不需要演员表,你应该避免不必要的演员表 - 不正确的演员表可以掩盖真正的错误。)
e.g。
struct Data *tData = threadData;
答案 2 :(得分:3)
LPVOID作为指向结构的指针而不是结构本身。所以你想要的东西是:
struct Data * ptData = (struct Data *)threadData;
然后您需要使用->
运算符访问字段:
blahblah = ptData->messages;
但是。当你填充它时,你也缺少为结构分配的存储空间,因为你正在使用没有任何后备内存的指针。你需要malloc
结构。您应该阅读C中的内存管理。(在许多其他链接中,this one讨论结构)
答案 3 :(得分:1)
您正在尝试将指针值(LPVOID
等效于void*
)转换为非指针值。这是不允许的。相反,您需要将其转换为不同的指针值,例如struct Data*
。
尝试以下
struct Data* pData = (struct Data*)threadData;
答案 4 :(得分:0)
将您的数据作为LPVOID
投射到CreateThread函数中hThread = CreateThread(
NULL, // lpThreadAttributes (default)
0, // dwStackSize (default)
ThreadFunc, // lpStartAddress
(LPVOID)tData, // lpParameter
0, // dwCreationFlags
&threadId // lpThreadId (returned by function)
)
同样在ThreadFunc中,Data应该是Data *
如果你去了LPVOID的定义,你会发现它只是指向虚空的指针。因为tData已经是一个指针,所以你不需要指针的地址。
答案 5 :(得分:0)
替换为:
struct Data *tData = (struct Data*)threadData;
答案 6 :(得分:0)
您的代码中还有其他错误... tData似乎没有分配..也是您使用&amp;地址运算符传递它,因此您传递指针的地址而不是指针。可能当你得到指针并使用它时,你得到一个AccessViolation